首页 > 解决方案 > 如何使用 ES2016 按多个条件过滤对象数组?

问题描述

// all products
let products = [
  { name: "A", fabricColor: {"id": 'BLUE'}, pattern: {'id': 'PLAID'}, size: 50 },
  { name: "B", fabricColor: {"id": 'BLUE'}, pattern: {'id': 'WINDOWPANE'}, size: 60 },
  { name: "C", fabricColor: {"id": 'BLUE'}, pattern: {'id': 'SOLID'}, size: 100 },
  { name: "D", fabricColor: {"id": 'BLACK'}, pattern: {'id': 'PLAID'}, size: 70 },
  { name: "E", fabricColor: {"id": 'BLACK'}, pattern: {'id': 'WINDOWPANE'}, size: 80 },
  { name: "F", fabricColor: {"id": 'BLACK'}, pattern: {'id': 'SOLID'}, size: 100 },
  { name: "G", fabricColor: {"id": 'GREEN'}, pattern: {'id': 'PLAID'}, size: 90 },
  { name: "H", fabricColor: {"id": 'GREEN'}, pattern: {'id': 'SOLID'}, size: 100 },
  { name: "I", fabricColor: {"id": 'GREEN'}, pattern: {'id': 'WINDOWPANE'}, size: 80 }
];

// filters applied
let filters = {
  fabricColor: [{"id": 'BLUE'}, {"id": 'BLACK'}],
  pattern: [{'id': 'PLAID'}, {'id': 'WINDOWPANE'}]
};


var filtered = multiFilter(products, filters);


/**
 * Multi-filter an array of objects
 * @param  {Array}  array  : list of elements to apply a multiple criteria filter
 * @param  {Object} filters: Contains multiple criteria filters by the property names of the objects to filter
 * @return {Array}
 */
function multiFilter(array, filters) {
  let filterKeys = Object.keys(filters);
  // filters all elements passing the criteria
  let filterData = array.filter((item) => filterKeys.every((key) => (filters[key].indexOf(item[key]) !== -1)));
  return filterData
}



 // expected result 
let expected = [
  { name: "A", fabricColor: {"id": 'BLUE'}, pattern: {'id': 'PLAID'}, size: 50 },
  { name: "B", fabricColor: {"id": 'BLUE'}, pattern: {'id': 'WINDOWPANE'}, size: 60 },
  { name: "D", fabricColor: {"id": 'BLACK'}, pattern: {'id': 'PLAID'}, size: 70 },
  { name: "E", fabricColor: {"id": 'BLACK'}, pattern: {'id': 'WINDOWPANE'}, size: 80 }
];

我尝试使用上面的代码,但无法根据过滤条件进行过滤。过滤结果应与预期结果匹配。

非常感谢您的帮助或任何参考。

标签: javascript

解决方案


你可以filter得到如下结果

let products = [
  { name: "A", fabricColor: {"id": 'BLUE'}, pattern: {'id': 'PLAID'}, size: 50 },
  { name: "B", fabricColor: {"id": 'BLUE'}, pattern: {'id': 'WINDOWPANE'}, size: 60 },
  { name: "C", fabricColor: {"id": 'BLUE'}, pattern: {'id': 'SOLID'}, size: 100 },
  { name: "D", fabricColor: {"id": 'BLACK'}, pattern: {'id': 'PLAID'}, size: 70 },
  { name: "E", fabricColor: {"id": 'BLACK'}, pattern: {'id': 'WINDOWPANE'}, size: 80 },
  { name: "F", fabricColor: {"id": 'BLACK'}, pattern: {'id': 'SOLID'}, size: 100 },
  { name: "G", fabricColor: {"id": 'GREEN'}, pattern: {'id': 'PLAID'}, size: 90 },
  { name: "H", fabricColor: {"id": 'GREEN'}, pattern: {'id': 'SOLID'}, size: 100 },
  { name: "I", fabricColor: {"id": 'GREEN'}, pattern: {'id': 'WINDOWPANE'}, size: 80 }
];

// filters applied
let filters = {
  fabricColor: [{"id": 'BLUE'}, {"id": 'BLACK'}],
  pattern: [{'id': 'PLAID'}, {'id': 'WINDOWPANE'}]
};

let res = products.filter(d => Object.entries(filters).every(([k ,v]) => 
                                  Object.values(v).map(m => m.id).includes(d[k].id) ))

console.log(res)


推荐阅读