具有以下结构:
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}]
如何过滤此数组以获得以下结果:
filteredTasks =
[{status: 'done', other: false}, {status: 'done', other: false}]
我的想法和尝试:
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;
})
}
...但是很明显,这遍及了每遍。
一如既往,我们非常感谢您提供反馈和帮助,因此在此先致谢。
编辑: 接受最初的评论作为适合我需要的解决方案。我用它来更进一步:
let filterTaskList = (list, filters) => {
let entries = Object.entries(Object.assign(...filters))
return list.filter(task => {
return entries.every(([key, val]) => {
return task[key] === val
})
})
}
答案 0 :(得分:3)
您可以创建过滤器的单个对象,并获取用于过滤的条目。
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);
答案 1 :(得分:0)
代码优先:
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)))
说明:这里的两个有趣的功能是matchesFilter
和withFilters
。
matchesFilter
:获取一个对象filter
,并将每个键/值与item
进行比较以确保匹配。
withFilters
接收一个过滤器列表,并返回一个可以与Array.prototype.filter
一起使用以生成过滤器列表的函数。
然后,您只需使用withFilters(availableFilters)
作为过滤器功能即可。您甚至可以保存该结果,以便以后再次使用。
let filterByAvailable = withFilters(availableFilters)
let availableTaks = filteredTasks.filter(filterByAvailable)