我正在尝试制作过滤器。过滤器的数量会动态变化,键的数量可以不同,值的数量也是如此。
这是数据的样子:
var data = [
{id: "123", color: "Red", model: "Tesla"},
{id: "124", color: "Black", model: "Honda"},
{id: "125", color: "Red", model: "Audi"},
{id: "126", color: "Blue", model: "Tesla"}]
Run Code Online (Sandbox Code Playgroud)
过滤键是颜色和型号。但有时我会只按颜色或型号过滤,有时两者都过滤。我想创建一个涵盖这两种情况的函数。此外,用户可以选择许多值(特斯拉、本田...)。
键可以只有颜色,也可以只有型号,或者两者都有。值可能看起来像:只有“红色”、“红色”和“蓝色”,或“红色”和“特斯拉”,或“红色”、“蓝色”和“特斯拉”......取决于用户选择什么。
我试过这个:
var filtered = [];
data.forEach(item => {
filterByKey.forEach(key => {
values.forEach(value => {
if (item[key] === value) {
filtered.push(item);
}
});
});
});
Run Code Online (Sandbox Code Playgroud)
这是JsFiddle
当我有一个过滤键时,我的循环效果很好,但当我有多个键时,它就不好用了。将键和值作为数组传递是个好主意吗?
请不要使用 jQuery,只使用纯 JavaScript。
您可以使用filter()withevery()并检查当前对象的值与当前键是否存在于values数组中includes()
var data = [{"id":"123","color":"Red","model":"Tesla"},{"id":"124","color":"Black","model":"Honda"},{"id":"125","color":"Red","model":"Audi"},{"id":"126","color":"Blue","model":"Tesla"}]
var keys = ["color", 'model'];
var values = ["Tesla", "Audi", "Red"];
var result = data.filter(function(e) {
return keys.every(function(a) {
return values.includes(e[a])
})
})
console.log(result);Run Code Online (Sandbox Code Playgroud)
您可以使用Array.prototype.filter(),其中测试数组每个元素的函数是:
el => !!filterBy.toString().match(new RegExp(`(?=.*${el.color})(?=.*${el.model})`))
new RegExp(`(?=.*${el.color})(?=.*${el.model})`))它由匹配字符串color和model另一个字符串的正则表达式组成filterBy.toString()
var data = [{id: "123", color: "Red", model: "Tesla"}, {id: "124", color: "Black", model: "Honda"}, {id: "125", color: "Red", model: "Audi"}, {id: "126", color: "Blue", model: "Tesla"}],
filterBy = ['Tesla', 'Audi', 'Red', 'Black'],
result = data.filter(el => !!filterBy.toString().match(new RegExp(`(?=.*${el.color})(?=.*${el.model})`)));
console.log(result);Run Code Online (Sandbox Code Playgroud)
而且,您可以组合Array.prototype.filter()和Array.prototype.includes():
var data = [{id: "123", color: "Red", model: "Tesla"}, {id: "124", color: "Black", model: "Honda"}, {id: "125", color: "Red", model: "Audi"}, {id: "126", color: "Blue", model: "Tesla"}],
filterBy = ['Tesla', 'Audi', 'Red', 'Black'],
result = data.filter(el => filterBy.includes(el.model) && filterBy.includes(el.color));
console.log(result);Run Code Online (Sandbox Code Playgroud)
您可以使用带有保留条件的搜索对象的组合方法,例如
Run Code Online (Sandbox Code Playgroud){ model: 'Tesla', // a single value color: ['red', 'blue'], // a some value price: { // a range/interval min: 2000, max: 3000 }, transmission: v => v.toLowerCase() === 'automatic' // a function }
{
model: 'Tesla', // a single value
color: ['red', 'blue'], // a some value
price: { // a range/interval
min: 2000,
max: 3000
},
transmission: v => v.toLowerCase() === 'automatic' // a function
}
Run Code Online (Sandbox Code Playgroud)