如何使用ES2016在多个条件下过滤对象数组?

时间:2018-11-25 06:17:00

标签: javascript

// 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 }
];

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

几乎没有帮助或高度赞赏的参考。

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

您可以在some的帮助下reduce使用过滤器(其中返回的累加器是应用了提供的过滤器之一后的旧累加器的过滤版本):

function multiFilter(array, filters) {
  return Object.entries(filters).reduce((acc, [k, v]) => {
    // for a product to qualify, it should match at least one of
    // the filters for this property "k"
    return acc.filter(a => v.some(f => f.id === a[k].id))
  }, array);
}


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 }
];

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

var filtered = multiFilter(products, filters);
console.log(filtered);