我有一堆存储在对象中的过滤条件。标准会不时变化,因此我无法使用静态过滤器(即:price > 5 && price < 19 && ...
)。
var criteria = {
price: {
min: 5,
max: 19
},
age: {
max: 35
}
};
然后我有一个循环设置来根据条件过滤数组并返回过滤后的数组:
var filtered = [];
var add = true;
for (var i=0; i < data.length; i++ ){
add = true;
var item = data[i];
for (var main in criteria){
for (var type in criteria[main] ){
if ( type === 'min') {
if ( !(item[main] > criteria[main][type]) ) {
add = false;
break;
}
} else if ( type === 'max') {
if ( !(item[main] < criteria[main][type]) ) {
add = false;
break;
}
}
}
}
if (add) {
filtered.push(item);
}
}
是否有更有效的方法提前设置过滤条件(即:item.price > 5 && item.price < 19 && item.age < 35
)然后过滤数组?与我目前正在进行的操作相反,并在每个数组循环期间引用该对象 - 这对于所有条件和子循环都是低效的。
请参阅我的jsbin - http://jsbin.com/celin/2/edit。
答案 0 :(得分:3)
var filtered = data.filter(function (item) {
var main, critObj;
for (main in criteria) {
critObj = criteria[main];
if (critObj.min && critObj.min >= item[main]) {
return false;
}
if (critObj.max && critObj.max <= item[main]) {
return false;
}
}
return true;
});
如果它不应包含在您的过滤列表中,请返回false
。在for循环中,该函数只检查条件是否有min,以及是否大于数组项中的相同属性。如果是这样,它只会为此元素返回false(当然对于max-property也是如此)。
如果两者都适合,则函数返回true,并且我将包含在过滤后的列表中!
编辑:现在使用fixed bin
答案 1 :(得分:1)
我一直在研究 Ramda 库,使用它来做这件事非常简单:
var test = R.allPredicates(R.reduce(function(tests, key) {
var field = criteria[key];
if ('min' in field) {tests.push(R.pipe(R.prop(key), R.gt(R.__, field.min)));}
if ('max' in field) {tests.push(R.pipe(R.prop(key), R.lt(R.__, field.max)));}
return tests;
}, [], R.keys(criteria)));
console.log( 'filtered array is: ', data.filter(test) );
(也可在 JSBin 中找到。)
要在没有库的情况下执行此操作,我将上面的代码转换为无库版本,它有点复杂,但仍然可读:
var test = (function(criteria) {
var tests = Object.keys(criteria).reduce(function(tests, key) {
var field = criteria[key];
if ('min' in field) {tests.push(function(item) {
return item[key] > field.min;
});}
if ('max' in field) {tests.push(function(item) {
return item[key] < field.max;
});}
return tests;
}, []);
return function(item) {
return tests.every(function(test) {return test(item);});
};
}(criteria));
console.log( 'filtered array is: ', data.filter(test) );
(的 JSBin 强>)
在任一版本中,标准都会被解析一次以创建一组谓词函数。这些函数组合成一个谓词,作为过滤器传递。