[英]How to efficiently construct new object array using unique values from arrays of children inside an array of parent objects
The need is to take objects like this:需要采取这样的对象:
[ { "first":
{ "children" : [{ "name": "abc", "detail":"123"},
{ "name": "def", "detail":"456"}
]
}},
{ "second":
{ "children" : [{ "name": "ghi", "detail":"123"},
{ "name": "jkl", "detail":"456"}
]
}},
{ "third":
{ "children" : [{ "name": "mno", "detail":"123"},
{ "name": "pqr", "detail":"456"}
]
}},
{ "fourth":
{ "children" : [{ "name": "stu", "detail":"123"},
{ "name": "vwx", "detail":"456"}
]
}},
{ "fifth":
{ "children" : [{ "name": "yz", "detail":"123"},
{ "name": "abc", "detail":"456"}
]
}},
{ "sixth":
{ "children" : [{ "name": "def", "detail":"123"},
{ "name": "ghi", "detail":"456"}
]
}}
]
and then create a flattened array of unique values (options for a select) from the name field of the children that looks like this:然后从子项的 name 字段创建一个扁平化的唯一值数组(选择的选项),如下所示:
[{"value":"abc", "label":"abc"},
{"value":"def", "label":"def"},
{"value":"ghi", "label":"ghi"},
{"value":"jkl", "label":"jkl"},
{"value":"mno", "label":"mno"},
{"value":"pqr", "label":"pqr"},
{"value":"stu", "label":"stu"},
{"value":"vwx", "label":"vwx"},
{"value":"yz", "label":"yz"}
]
The code below is working, but it looks like it is inefficient because it appears to make many passes over the array:下面的代码正在运行,但看起来效率低下,因为它似乎对数组进行了多次传递:
[
...new Set(
[].concat.apply([], bases.map((base) => {
if (!base.children || base.children.length === 0) return;
return base.children}
)).map((child) => child.name)
)
].map((optName) => {return {value: optName, label: optName};})
If it is possible, how can this same result be achieved without as many iterations across the array.如果可能的话,如何在不跨阵列进行多次迭代的情况下实现相同的结果。
Firstly, as a rule of thumb, you shouldn't worry too much about performance until you have a reason to do so.首先,根据经验,在有理由这样做之前,您不应过分担心性能。
Secondly, chaining the array prototype functions (eg map, forEach, filter) will require multiple iterations by design.其次,按照设计链接数组原型函数(例如 map、forEach、filter)将需要多次迭代。
Thirdly, there's no reason to assume multiple iterations is slower than a single iteration if the work done within the iterations is the same anyways.第三,如果迭代中完成的工作无论如何都相同,则没有理由假设多次迭代比单次迭代慢。 Ie incrementing an index and comparing it with an array length isn't going to be the bottleneck compared to pushing objects into arrays and check set entries.
即,与将对象推入数组并检查集合条目相比,增加索引并将其与数组长度进行比较不会成为瓶颈。
Here's a (IMO) cleaner snippet to extract unique names from your array:这是一个(IMO)更清晰的片段,用于从您的数组中提取唯一名称:
let bases = [{ children: [{ name: "abc", detail: "123" }, { name: "def", detail: "456" } ] }, { children: [{ name: "abc" , detail: "123" }, { name: "xyz" , detail: "456" } ] }, {} ]; let output = bases .flatMap(b => b.children || []) .map(c => c.name) .filter((v, i, a) => a.indexOf(v) === i) // filter unique values .map(name => ({ value: name, label: name, })); console.log(output);
Now if you really want to do all this in a single iteration, that too is possible, but harder to read:现在,如果你真的想在一次迭代中完成所有这些,那也是可能的,但更难阅读:
let bases = [{ children: [{ name: "abc", detail: "123" }, { name: "def", detail: "456" } ] }, { children: [{ name: "abc" , detail: "123" }, { name: "xyz" , detail: "456" } ] }, {} ]; let output = []; let seenNames = {}; for (base of bases) { if (!base.children) continue; for (child of base.children) { let name = child.name; if (seenNames[name]) continue; seenNames[name] = true; output.push({ value: name, label: name, }); } } console.log(output);
You could take Array#flatMap
for getting a flat representation of data for using unique values and map new objects.您可以使用
Array#flatMap
来获取数据的平面表示,以使用唯一值和映射新对象。
var data = [{ first: { children: [{ name: "abc", detail: "123" }, { name: "def", detail: "456" }] } }, { second: { children: [{ name: "ghi", detail: "123" }, { name: "jkl", detail: "456" }] } }, { third: { children: [{ name: "mno", detail: "123" }, { name: "pqr", detail: "456" }] } }, { fourth: { children: [{ name: "stu", detail: "123" }, { name: "vwx", detail: "456" }] } }, { fifth: { children: [{ name: "yz", detail: "123" }, { name: "abc", detail: "456" }] } }, { sixth: { children: [{ name: "def", detail: "123" }, { name: "ghi", detail: "456" }] } }], result = Array.from( new Set(data .flatMap(Object.values) .flatMap(({ children }) => children.map(({ name }) => name)) ), value => ({ value, label: value }) ); console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.