简体   繁体   English

es6按过滤器对象数组过滤对象数组

[英]es6 filter an array of objects by an array of filter objects

given the following structure: 给出以下结构:

let filteredTasks = [
  {status: 'done', other: true},
  {status: 'nope', other: false},
  {status: 'done', other: true},
  {status: 'done', other: true},
  {status: 'done', other: false},
  {status: 'done', other: false},
  {status: 'started', other: false}
]

and: 和:

let availableFilters = [{status: 'done'}, {other: false}]

how can I filter this array to get the following results: 如何过滤此数组以获得以下结果:

filteredTasks =
[{status: 'done', other: false}, {status: 'done', other: false}]

my thoughts and attempts: 我的想法和尝试:

let filteredTasks = [
  {status: 'done', other: true},
  {status: 'nope', other: false},
  {status: 'done', other: true},
  {status: 'done', other: true},
  {status: 'done', other: false},
  {status: 'done', other: false},
  {status: 'started', other: false}
]

let availableFilters = [{status: 'done'}, {other: false}]

let filteredTasksList = availableFilters.map(item => {
    return runFilter(item)
})

function runFilter(currentFilter) {
  return filteredTasks.filter(item => {
    for (var key in currentFilter) {
        if (item[key] === undefined || item[key] !== currentFilter[key])
        return false
    }
    return true;
  })
}

...but obviously this is overriding each pass. ......但显然这是每次通过的最重要的。

As always any feedback and help is greatly appreciated, so thanks in advance. 一如既往的任何反馈和帮助非常感谢,所以提前感谢。

EDIT: accepted the initial comment as the solution as it fits my needs. 编辑:接受最初的评论作为解决方案,因为它符合我的需要。 I used that to take it a step further: 我用它来更进一步:

let filterTaskList = (list, filters) => {
  let entries = Object.entries(Object.assign(...filters))
  return list.filter(task => {
    return entries.every(([key, val]) => {
      return task[key] === val
     })
  })
}

You could create a single object of the filters and take the entries for filtering. 您可以创建过滤器的单个对象并将条目用于过滤。

 let filteredTasks = [ {status: 'done', other: true}, {status: 'nope', other: false}, {status: 'done', other: true}, {status: 'done', other: true}, {status: 'done', other: false}, {status: 'done', other: false}, {status: 'started', other: false} ], availableFilters = [{status: 'done'}, {other: false}], // your filters filters = Object.entries(Object.assign(...availableFilters)), // returns an array of the filter's own enumerable property result = filteredTasks.filter(o => filters.every(([k, v]) => o[k] === v)); // .every returns true, when every item is fulfilling the condition console.log(result); 

Code first: 代码优先:

 let filteredTasks = [ {status: 'done', other: true}, {status: 'nope', other: false}, {status: 'done', other: true}, {status: 'done', other: true}, {status: 'done', other: false}, {status: 'done', other: false}, {status: 'started', other: false} ] let availableFilters = [{status: 'done'}, {other: false}] const matchesFilter = (filter, item) => Object.entries(filter).every(([key, value]) => item[key] === value) function withFilters (filters) { return item => filters.every(f => matchesFilter(f, item)) } console.log(filteredTasks.filter(withFilters(availableFilters))) 

Explanation: the two interesting functions here are matchesFilter and withFilters . 说明:这里有两个有趣的函数是matchesFilterwithFilters

matchesFilter : takes an object, the filter and compares every key/value to the item to ensure it matches. matchesFilter :获取一个对象, filter并将每个键/值与item进行比较以确保它匹配。

withFilters takes in a list of filters and returns a function that can be used with Array.prototype.filter to produce a filtered list. withFilters接收过滤器列表并返回一个可与Array.prototype.filter一起使用的函数,以生成过滤列表。

You then just use withFilters(availableFilters) as your filter function. 然后,您只需使用withFilters(availableFilters)作为过滤器函数。 You can even save that result to re-use it later. 您甚至可以保存该结果以便以后重复使用。

let filterByAvailable = withFilters(availableFilters)
let availableTaks = filteredTasks.filter(filterByAvailable)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM