JS Array.filter与动态过滤标准
JS Array.filter with Dynamic Filter Criterion
如何动态声明一组筛选器条件而不必指定筛选器的数量?
例如,如果我有一组数据,比如:
var data = [
{ item: { type: 'wood', size: 10 } },
{ item: { type: 'wood', size: 8 } },
{ item: { type: 'metal', size: 8 } }
]
我知道我可以使用JS .filter()
来获得所有具有type
wood
和size
8
:的项目
function filterItems() {
return data.filter(function(val) {
return val['item'].type == 'wood' &&
val['item'].size == 8;
}
}
但是,如果我想用未知数量的过滤器过滤项目,并让.filter()
返回所有符合这些条件的data
项目,该怎么办?
这是一个反映上述代码的代码笔。
您可以将一组条件传递给filterItems()
函数。试试这个:
function filterItems(filters) {
return data.filter(function(val) {
for(var i = 0; i < filters.length; i++)
if(val['item'][filters[i][0]] != filters[i][1])
return false;
return true;
}
}
filterItems([['type', 'wood'], ['size', 8], ['someother', 'value']]);
同样的想法可以应用于各种格式,例如使用对象而不是数组来提高可读性。
对于任何支持的数据结构和嵌套属性,我刚刚对Amit的答案进行了一行重构
// the function
filterItems = (data, filters) => data.filter(item => !filters.find(x => x.key.split('.').reduce((keys, key) => keys[key], item) !== x.value))
// how to use it
filterItems(data, [{ key: 'type', value: 'wood' }, { key: 'some.nested.prop', value: 'value' }])
function isSingle(filter) {
return (filter && 'o' in filter && 'm' in filter && 'v' in filter);
}
function isComposite(filter) {
return (filter && 'lo' in filter);
}
function createBody(filter) {
if (isComposite(filter)) {
var bdy = "";
if (filter.v.length > 1) {
var o = filter.lo;
return "(" + createBody(filter.v.shift()) + " " + o + " " + createBody({ lo: filter.lo, v: filter.v }) + ")";
} else if (filter.v.length == 1) {
return createBody(filter.v.shift());
}
return bdy;
} else if (isSingle(filter)) {
var o = filter.o;
if (typeof filter.v == "string") filter.v = "'" + filter.v + "'"
return "item." + filter.m + " " + o + " " + filter.v;
}
}
var createFunc = function (filter) {
var body = createBody(filter);
var f = new Function("item", " return " + body + ";");
return f;
}
function applyFilter(input, filter) {
if (filter == undefined) {
return input;
}
var fun = createFunc(filter);
var output = input.filter(fun);
return output;
};
//m:member,o:operator,v:value.
var filterQuery1 = { m: "item.type", o: "==", v: "metal" };//simpe query
var filterQuery2 = { m: "item.size", o: ">", v: 8 };
var filterQuery3 = {
lo: "&&", v: [
{ m: "item.type", o: "==", v: "metal" },
{ m: "item.size", o: "<", v: 9 }]
}; //composite query
var data = [
{ item: { type: 'wood', size: 10 } },
{ item: { type: 'wood', size: 8 } },
{ item: { type: 'metal', size: 8 } }
]
var result = applyFilter(data, filterQuery1);// or filterQuery2,filterQuery3
console.log(result);
https://jsfiddle.net/kd0kL098/
Amit的答案很好,但我想添加它。在我的情况下,我需要返回所有参数,否则返回none/false。这是Amit 的编辑代码
function filterItems(filters) {
return data.filter(function(val) {
let result = true;
for(var i = 0; i < filters.length; i++)
if(val['item'][filters[i][0]] != filters[i][1])
result = false;
return result;
}
}
filterItems([['type', 'wood'], ['size', 8], ['someother', 'value']]);
相关文章:
- 有可能过滤来自嵌入式YouTube的声音吗
- 为什么我的d3.jsselectAll+过滤器没有过滤
- 在哪里可以学习ECMAScript标准中尚未包含的JavaScript功能
- ui网格日期单元格过滤器,过滤日期格式导致显示错误的日期
- Angular:使用选择列表选择过滤代码中的对象
- 如何允许web浏览器记住未以标准方式发送的表单字段
- 在单击时过滤 JSON
- 如何在BookshelfJS中通过加入来过滤结果
- 如何使用javascript过滤复杂的json对象
- 如何应用带过滤器的ng if来过滤记录,并在同一页面中显示两个不同的视图
- 命名约定的Web标准
- 过滤AngularJs中的数据
- 通过API调用过滤数据
- 使用angularjs内置过滤器过滤代码中的特定属性
- 如何在重建URL后从URL中传递过滤值,目的是使用Angular2和Typescript实现无限滚动
- 相对于角度控制器中的另一个阵列过滤阵列项目
- 用于编码标准的javascript工具
- 如何使用javascript过滤许多标准
- JS Array.filter与动态过滤标准
- 使用正则表达式过滤掉不符合't不符合标准