按多个键和值过滤,Javascript

时间:2017-06-16 13:22:12

标签: 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"}]

过滤键是颜色和型号。但有时我会只按颜色或模型过滤,有时候两者都过滤。我想制作一个涵盖这两种情况的功能。此外,用户可以选择许多值(特斯拉,本田......)。

键只能是颜色,或只是模型,或两者兼而有之。 值可能如下:只有“红色”,“红色”和“蓝色”,或“红色”和“特斯拉”,或“红色”,“蓝色”和“特斯拉”......取决于用户选择的内容。

我试过了:

var filtered = [];
data.forEach(item => {
   filterByKey.forEach(key => {
      values.forEach(value => {
         if (item[key] === value) {
             filtered.push(item);
          }
       });
    });
  });

这是JsFiddle

当我有一个过滤器键时,我的循环效果很好,但是当我有多个键时它不能正常工作。将键和值作为数组传递是一个好主意吗?

请不要jQuery,只有纯JavaScript。

8 个答案:

答案 0 :(得分:3)

您可以将filter()every()一起使用,并使用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);

答案 1 :(得分:2)

您可以合并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);

.as-console-wrapper { max-height: 100% !important; top: 0; }




答案 2 :(得分:2)

您可以将组合方法与保持条件的搜索对象结合使用,例如

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



var useConditions = search => a => Object.keys(search).every(k => 
        a[k] === search[k] ||
        Array.isArray(search[k]) && search[k].includes(a[k]) ||
        typeof search[k] === 'object' && +search[k].min <= a[k] &&  a[k] <= +search[k].max ||
        typeof search[k] === 'function' && search[k](a[k])
    ),
    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" }],
    filters = { color: ['Red', 'Blue'], model: 'Tesla' };

console.log(data.filter(useConditions(filters)));
&#13;
&#13;
&#13;

答案 3 :(得分:1)

对于这种情况,这就是我要做的事情:

function _filter(data, query) { // query = "Red" or "Tesla"
    return data.filter(el => {
        return el.model.toLowerCase().indexOf(query.toLowerCase()) !== -1 ||
        el.name.toLowerCase().indexOf(query.toLowerCase()) !== -1;
    });
}

现在,此功能可以搜索型号键和名称键上的数据。

答案 4 :(得分:0)

这是你想要达到的目标吗?

&#13;
&#13;
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 allowedColors = ["Red", "Blue"];
var allowedModels = ["Tesla", "Audi"];

function filter (cars, colors, models) {
  return cars.filter(function (car) {
    return colors.indexOf(car.color) !== -1 && // check if the car's color is allowed
      models.indexOf(car.model) !== -1;        // check if the car's model is allowed
  });
}

var filtered = filter(data, allowedColors, allowedModels);
console.log(filtered);
&#13;
&#13;
&#13;

答案 5 :(得分:0)

过滤在JS中是原生的,试试这个:

data.filter(item => item.color==='Red');
// or in the old fashion 
data.filter(function(item){ return item.color==='Red';} );

答案 6 :(得分:0)

在这里,我有不同的情况。

我有一个对象

d={r1: {name: "r1", validation: true}, r2: {name: "r2", validation: true}};

和另一个数组

a = ["r1"];

在这里,我想要的结果是

d={r1: {name: "r1", validation: true}}

答案 7 :(得分:0)

enter image description here

使用filter()过滤数据,结合some()检查多个keys是否匹配至少一个来自values的字符串使用 includes()

// array --------------------

const 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' },
];



// filter exact match --------------------

const keysExact = ['color', 'model'];
const valuesExact = ['Tesla', 'Audi', 'Red'];

const resultExact = data.filter((item) =>
  keysExact.every((a) => valuesExact.includes(item[a]))
);

console.log(resultExact);
// result:
// [
//   { id: '123', color: 'Red', model: 'Tesla' },
//   { id: '125', color: 'Red', model: 'Audi' },
// ]; 

enter image description here

使用filter()过滤数据,结合some()检查多个keys是否包含至少一个来自values的字符串使用 includes()

// array --------------------

const 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' },
];



// filter data by keys containing values string (at least one of the string in values) --------------------

const keysSome = ['color', 'model'];
const valuesSome = ['Tes', 're'];

const resultSome = data.filter((item) =>
  keysSome.some((key) =>
    valuesSome.some((val) => item[key].toLowerCase().includes(val.toLowerCase()))
  )
);

console.log(resultSome);
// result:
// [
//   { id: '123', color: 'Red', model: 'Tesla' },
//   { id: '125', color: 'Red', model: 'Audi' },
//   { id: '126', color: 'Blue', model: 'Tesla' },
// ];

enter image description here

使用filter()过滤数据,结合every()使用{{1}检查多个keys是否包含来自valuesall字符串}}。

includes()