如何在不使用eval()的情况下从javascript for循环中的字符串创建if条件语句



我正在尝试创建一个高级搜索函数,用于产品对象的多维数组。在表单上,用户可以选择根据几个不同属性的数据缩小产品结果的范围(例如"价格"<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循环中,但我不知道如何让它工作。棘手的是,条件可能是涉及以下产品属性的任何数量的东西:名称、国家、价格、主要葡萄、数量、地区、年份。不同的属性使用不同的运算符(例如,国家、地区和其他使用'==',而数量和价格使用'>'或'<')。

此代码有效,但使用了禁忌的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]);
}
}
}

知道如何动态创建if条件语句,以便它识别data变量吗?或者,有更好的解决方案吗?

Javascript数组有一个名为filter的函数,可以用来完成您想要实现的任务。

例如,您有一个带有数字的数组:

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

你的计划是过滤所有偶数。您可以使用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)

如果您是根据用户输入获得条件的,您可以随心所欲地格式化它,它不需要是字符串。我推荐一个看起来像这样的阵列:

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

然后你可以使用过滤方法来生成你的结果数组:

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;
}
}
})

最新更新