提问人:Srilatha Danalakota 提问时间:9/26/2023 最后编辑:evolutionxboxSrilatha Danalakota 更新时间:9/26/2023 访问量:62
从对象数组创建嵌套对象 [已关闭]
create a nested object from array of objects [closed]
问:
let list=[{key1,children[]},{key2,children[]},{key3,children[]}]
如何使用 javascript 获得这样的数组?
list1=[{key1,children[{key2,children[{key3,children[]}]}]}
我试过这样
for (let i = 0; i < list.length; i++) {
if (list[i + 1]) {
list[0].children.push(list[i + 1]);
}
}
但它把所有的孩子都推入了list[0].children
答:
0赞
Jamiec
9/26/2023
#1
您需要以相反的顺序处理原始列表,应该这样做:
let list=[{"key":"key1", "children":[]},{"key":"key2", "children":[]},{"key":"key3", "children":[]}]
let result = list.reverse().reduce( (acc,x,i, e) => {
if(i == list.length-1){
acc.push(x);
}
else{
e[i+1].children = [x]
}
return acc;
},[]);
console.log(result);
0赞
Mr. Polywhirl
9/26/2023
#2
这是 Jamiec 答案的替代解决方案。
当数据被转换时,它不会发生变异,因为创建了 。我还从右到左减少了,因为当到达时,我们将返回]。我们确实需要为 reducer 初始化值设置一个非值。该值将起作用。list
structuredClone
index
0
[item
undefined
null
当 大于 时,将 作为 推到它的左侧。index
0
item
child
const list = [
{ key: "key1", children: [] },
{ key: "key2", children: [] },
{ key: "key3", children: [] }
]
const transformed = structuredClone(list)
.reduceRight((acc, item, index, ref) => {
if (index === 0) return [item];
ref[index - 1].children.push(item);
}, null);
console.log(transformed);
.as-console-wrapper { top: 0; max-height: 100% !important; }
@Jamiec,您可以更改索引,而不是反转列表。小心,这仍然修改了原来的数组!list
const list = [
{ key: "key1", children: [] },
{ key: "key2", children: [] },
{ key: "key3", children: [] }
]
let result = list.reduce((acc, x, i, e) => {
if (i === 0) {
acc.push(x);
} else {
e[i - 1].children = [x]
}
return acc;
}, []);
console.log(result);
.as-console-wrapper { top: 0; max-height: 100% !important; }
0赞
Alexander Nenashev
9/26/2023
#3
不惜一切代价避免,因为除非您希望保留对象引用,否则克隆对象是一种缓慢的方法。而是在充当数据而不是功能对象的数据上使用。
对于您的情况,如果您想要数据的副本,只需创建您的自定义函数:structuredClone()
JSON.parse(JSON.stringify(object))
clone()
const list = [
{ key: "key1", children: [] },
{ key: "key2", children: [] },
{ key: "key3", children: [] }
]
const clone = elem => ({key:elem.key, children:[...elem.children]});
const result = [];
let head = result[0] = clone(list[0]);
for(let i = 1; i < list.length; i++){
head.children.push(head = clone(list[i]));
}
console.log(result);
.as-console-wrapper { top: 0; max-height: 100% !important; }
基准测试速度提高 33 倍:structuredClone()
Cycles: 600000 / Chrome/117
---------------------------------------------------------
Alexander 38/min 1.0x 40 40 38 41 45
Polywhirl 1251/min 32.9x 1308 1272 1289 1251 1266
---------------------------------------------------------
https://github.com/silentmantra/benchmark
<script benchmark="600000">
const list = [
{ key: "key1", children: [] },
{ key: "key2", children: [] },
{ key: "key3", children: [] }
]
// @benchmark Polywhirl
structuredClone(list)
.reduceRight((acc, item, index, ref) => {
if (index === 0) return [item];
ref[index - 1].children.push(item);
}, null);
// @benchmark Alexander
const clone = elem => ({key:elem.key, children:[...elem.children]});
const result = [];
let head = result[0] = clone(list[0]);
for(let i = 1; i < list.length; i++){
head.children.push(head = clone(list[i]));
}
result;
</script>
<script src="https://cdn.jsdelivr.net/gh/silentmantra/benchmark/loader.js"></script>
评论
0赞
Alexander Nenashev
9/29/2023
@SrilathaDanalakota如果我的答案对你有用,请不要忘记接受它(复选框),谢谢!stackoverflow.com/help/someone-answers
评论