按多个键和值过滤,Javascript

sno*_*y25 6 javascript filter

我正在尝试制作过滤器。过滤器的数量会动态变化,键的数量可以不同,值的数量也是如此。

这是数据的样子:

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。

Nen*_*car 7

您可以使用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)


Yos*_*ero 6

您可以使用Array.prototype.filter(),其中测试数组每个元素的函数是:

el => !!filterBy.toString().match(new RegExp(`(?=.*${el.color})(?=.*${el.model})`))

new RegExp(`(?=.*${el.color})(?=.*${el.model})`))它由匹配字符串colormodel另一个字符串的正则表达式组成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)


Nin*_*olz 5

您可以使用带有保留条件的搜索对象的组合方法,例如

{ 
    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)

{ 
    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)