过滤对象数组一部分的更有效方法?



我有一个名为items的大型对象数组,具有以下结构:

abc: [{object0}, {object1}, ... {objectN}],
def: [...],
ghi: [...],
jkl: [...]

为了清楚起见,我简化了事情。 可以说,defghijkl包含与abc相同的对象数组结构。

每个object#都有许多属性,其中之一是hiddenhidden通常是假的,但对于abc数组中的一些对象,它是真的。

我想返回一个新的items实例,该实例删除了所有hidden=true对象。

这段代码实际上有效:

items = {
abc: items.abc.filter(item => item.hidden === false), 
def: tasks.def,
ghi: tasks.ghi,
jkl: tasks.jkl
};

但我想知道是否有更优雅的方式来实现这一目标?

罗伯特

你可以做这样的事情

const data = {
// your source data set
}
const items = {}
for(let key in data) {
items[key] = data[key].filter(item => item.hidden === false)
}

您可以将原始items(使用...运算符(传播到一个新对象(例如notHiddenItems(,然后过滤您想要的任何键。

const items = { 
// orginal items object 
};
let notHiddenItems = {...items);
notHiddenItems.abc.filter(each => !each.hidden);

以下函数将接受任何键/值组合。详细信息在演示中注释

let data = {
abc: [{x: 13, xx: 'x', hidden: false}, {x: 47, xx: 'y', hidden: true}, {x: 36, xx: 'z', hidden: false}],
def: [{x: 68, xx: 'z', hidden: false}, {x: 91, xx: 'x', hidden: false}, {x: 3, xx: 'y', hidden: true}],
ghi: [{x: 22, xx: 'v', hidden: false}, {x: 1, xx: 'z', hidden: true}, {x: 76, xx: 'w', hidden: false}],
jkl: [{x: 99, xx: 's', hidden: true}, {x: 7, xx: 'm', hidden: false}, {x: 66, xx: 'x', hidden: false}]
};
/*
Pass the data Object, the property to search for, and
one or more values to match
*/
const keepKV = (object, prop, ...values) => {
/*
Convert data Object into an Array of array pairs
ex.
let data = {'abc': [{...}, {...}, {...}], 'def': [...]}
to
data = [['abc',[{...}, {...}, {...}]], ['def', [...]]

Object.entries(object)...
*/
/*
Destructure the .map() parameter 
ex.
subKey = 'abc'
subArray = [{...}, {...}, {...}]
.map(([subKey, subArray]) => {...
*/
/*
The last return on each iteration is an array of pairs:
[subKey, [subArray]]
ex.
["jkl", [{...}, {...}, {...}]]
Each object of each subArray gets .filter() 

return [subKey, subArray.filter(subObject => [...values].includes(subObject[prop]))];
*/
/*
The entire returned Array of arrays is then converted 
back into an Object

Object.fromEntries(ArrayOfArrays)
*/
return Object.fromEntries(Object.entries(object).map(([subKey, subArray]) => {
return [subKey, subArray.filter(subObject => [...values].includes(subObject[prop]))];
}));
};
// Utility function that creates a ranged Number array
let range = Array(...Array(26)).map((_, i) => 5+i);
// Get all objects that has x: 5 to 30
const range5to30 = keepKV(data, 'x', ...range); console.log(`Key: 'x', Values: rangen
const range5to30 = ${JSON.stringify(range5to30, null, 2)}n`);
// Get all objects that has xx: 'z' and/or 'x'
const xZOnly = keepKV(data, 'xx', 'z', 'x');
console.log(`Key: 'xx', Values: 'z', 'x'n
const xZOnly = ${JSON.stringify(xZOnly, null, 2)}n`);
// Get all objects that has hidden: false
const notHidden = keepKV(data, 'hidden', false);
console.log(`Key: 'hidden', Values: falsen
const notHidden = ${JSON.stringify(notHidden, null, 2)}n`);
.as-console-wrapper {
width: 375px;
min-height: 100%;
margin-left: 25%;
}
.as-console-row {
border-bottom: 5px ridge #333
}
.as-console-row-code::first-line {
text-decoration: underline;
}
.as-console-row.as-console-row::after,
.as-console-row-code.as-console-row-code::after {
content:'';
padding:0;
margin:0;
border:0;
width:0;
}

最新更新