我有一个数组,我想从字符串
构建过滤谓词var testArray=[{Id:1,IsChecked:true},{Id:2,IsChecked:false},{Id:3,IsChecked:false}];
var predicate='IsChecked==true && Id<3'
var filteredArray= testArray.filter(i=>i ????predicate) ????
我试过了
//this works
var predicate='IsChecked==true'
var filterFunction=new Function("i","return i." + predicate)
//this throw an error (Id is not defined)
var predicate='IsChecked==true && Id<3'
var filterFunction=new Function("i","return i." + predicate)
如何从字符串构建谓词?
欢迎任何使用其他javascript库(如ramda和loadash)的想法。
答案 0 :(得分:1)
要从字符串制作,您需要使用eval
,这是不好的做法。
相反,predicte
可以是一个函数,它接受一个项目并使用它来执行条件。您只需要将此功能传递到filter
。
const testArray = [
{ Id:1, IsChecked: true},
{ Id:2, IsChecked: false}
];
const predicate = (item) => item.IsChecked == true;
const filteredArray = testArray.filter(predicate);
console.log(filteredArray);
&#13;
答案 1 :(得分:0)
您可以先将谓词处理为函数。
function processPredicate( predicate )
{
var items = predicate.split(/[\W$]+/); //split by a non word character including $ which can also be part of an identifier
//if the operand if all numbers, then parse them into a number
var operand1 = parseToNative( items[0] );
var operand2 = parseToNative( items[1] );
var operator = predicate.match(/[\W$]+/)[0];
var fReturn = () => false;
switch (operator)
{
case "<":
fReturn = (obj) => obj[operand1] < operand2;
break;
case ">":
fReturn = (obj) => obj[operand1] > operand2;
break;
case "<=":
fReturn = (obj) => obj[operand1] <= operand2;
break;
case ">=":
fReturn = (obj) => obj[operand1] >= operand2;
break;
case "==":
fReturn = (obj) => obj[operand1] == operand2;
break;
case "===":
default:
fReturn = (obj) => obj[operand1] === operand2;
}
return fReturn;
}
<强>演示强>
function parseToNative( val )
{
return isNaN( val ) ? (val == "true" || val == "false" ? val === "true" : val ) : Number(val);
}
function processPredicate( predicate )
{
var items = predicate.split(/[\W$]+/); //split by a non word character including $ which can also be part of an identifier
//if the operand if all numbers, then parse them into a number
var operand1 = parseToNative( items[0] );
var operand2 = parseToNative( items[1] );
var operator = predicate.match(/[\W$]+/)[0];
var fReturn = () => false;
switch (operator)
{
case "<":
fReturn = (obj) => obj[operand1] < operand2;
break;
case ">":
fReturn = (obj) => obj[operand1] > operand2;
break;
case "<=":
fReturn = (obj) => obj[operand1] <= operand2;
break;
case ">=":
fReturn = (obj) => obj[operand1] >= operand2;
break;
case "==":
fReturn = (obj) => obj[operand1] == operand2;
break;
case "===":
default:
fReturn = (obj) => obj[operand1] === operand2;
}
//console.log( operand1, operand2, operator, fReturn );
return fReturn;
}
var testArray=[{Id:1,IsChecked:true},{Id:2,IsChecked:false}];
var predicate1=processPredicate('IsChecked==true')
var predicate2=processPredicate('Id<2')
var output = testArray.filter( function(item){
return Object.keys( item ).some( s => predicate1( item ) );
})
console.log( output );
output = testArray.filter( function(item){
return Object.keys( item ).some( s => predicate2( item ) );
})
console.log( output );