如何创建JavaScript的for循环中的字符串,如果条件语句不使用的eval()

问题描述 投票:0回答:2

我试图创建产品对象的多维数组上使用高级搜索功能。在窗体上,用户将不得不缩减基于几个不同的属性的数据产品结果(的选项,例如“‘价格’<20 &&‘国家’==‘法国’”,“区域==‘纽约’&& '老式' == '2016' &&“数量> 20" )。中的数据,变量data内的格式如下:

    0:
        name: "Kedem Cream Red Concord"
        appellation: "New York"
        country: "United States"
        price: "10.99"
        primarygrape: "Concord"
        qty: "1"

        region: "New York"
        regprice: "10.99"
        sku: "230"
        vintage: "NV"
    1:
        name: "Kendall Jackson Vintner's Chardonnay"

        appellation: ""

        country: "United States"

        price: "14.99"

        primarygrape: "Chardonnay"
        qty: "35"

        region: "California"

        regprice: "18.99"
        sku: "345"

        vintage: "2016"
... continuing on over 10,000 product records

我想我可以创建基于用户输入的形式很容易凝聚了他们正在搜索的内容的字符串。不过,我需要一个安全的方式来评价我的函数返回resultsArray过滤的结果中该字符串

我能得到它与eval()功能工作,但我知道这是不是安全的或有效的。我也试图与投入的条件到一个数组,并试图将其写入for循环鬼混,但我无法弄清楚如何使它发挥作用。最棘手的部分是,这些条件可以是任何数量的涉及以下产品的事情属性:名称,国家,价格,primarygrape,数量,地域,年份。和不同的属性使用不同的运营商(例如国家,地区,和其他人使用“==”而数量和价格使用“>”或“<”)。

此代码的工作,但使用禁忌eval()功能:

var conditional = "data[i].price < 20 && data[i].country == 'France' && data[i].vintage == '2016'";

var resultArray = [];
console.log(data.length);
for (var i = 0; i < data.length; i++)
{
    if (eval(conditional))
        {
            resultArray.push(data[i]);
        }
    }
}

这是不行的,因为它会导致一个错误Uncaught ReferenceError: data is not defined

var conditional = "return data[i].price < 20 && data[i].country == 'France' && data[i].vintage == '2016'";

var resultArray = [];
console.log(data.length);
for (var i = 0; i < data.length; i++)
{
    if (new Function(conditional)())
        {
            resultArray.push(data[i]);
        }
    }
}

任何想法如何动态地创建,如果条件语句,以便它能够识别data变量?或者,有没有更好的解决办法?

javascript arrays object dynamic eval
2个回答
3
投票

JavaScript数组有一个函数调用filter它可以像你想实现被用来做的事情。

例如你有一个数字的数组:

var arr = [1,3,6,2,6]

和你的计划是过滤所有甚至numbers.You可以使用array.filter()。你需要通过一个匿名函数进去。该功能获取您有权访问当前元素的每个条目调用一次。你需要在这个函数返回一个布尔 - true意味着元素将是新的,过滤数组中

现在已完成的例子来过滤所有偶数:

arr.filter(function(element) {return element%2 == 0})

我希望这足以让你继续。 :-)在接下来的片断我做了一个小例子与您的数据阵列

 var your_data_array = [
 { 
       name: "Kendall Jackson Vintner's Chardonnay",
        appellation: "",
        country: "United States",
        price: "14.99",
        primarygrape: "Chardonnay",
        qty: "35",
        region: "California",
        regprice: "18.99",
        sku: "345",
        vintage: "2016" },
        { 
       name: "Kendall Jackson Vintner's Chardonnay",
        appellation: "",
        country: "United States",
        price: "14.99",
        primarygrape: "Chardonnay",
        qty: "35",
        region: "California",
        regprice: "18.99",
        sku: "345",
        vintage: "2016" },
        { 
       name: "Kendall Jackson Vintner's Chardonnay",
        appellation: "",
        country: "United States",
        price: "14.99",
        primarygrape: "Chardonnay",
        qty: "35",
        region: "California",
        regprice: "18.99",
        sku: "345",
        vintage: "2016" }
 ]
 
 var filtered_array = your_data_array.filter(function(dataElement) {
   return dataElement.country == "United States";
 })
 
 console.log(filtered_array)

2
投票

如果您收到基于用户输入的情况下,你可以格式化你怎么样,它并不需要是一个字符串。我建议一个数组,看起来是这样的:

var conditions = [
  {
    property: 'price',
    comparator: '<',
    value: 20
  },
  {
    property: 'country',
    comparator: '=',
    value: 'France'
  }
];

然后,您可以使用filter方法来生成结果阵列:

var resultArray = data.filter(function(item) {
  for (var i = 0; i < conditions.length; i++) {
    if (conditions[i].comparator === '=' && 
        item[conditions[i].property] !== conditions[i].value) {
      return false;
    }

    if (conditions[i].comparator === '>' && 
        item[conditions[i].property] <= conditions[i].value) {
      return false;
    }

   if (conditions[i].comparator === '<' && 
        item[conditions[i].property] >= conditions[i].value) {
      return false;
    }
  }
})
© www.soinside.com 2019 - 2024. All rights reserved.