数组里有多个对象,对象中相同的id 组成一个数组。放在他的子项有啥好的方法吗?求大佬给个最优解决方法
var array = [ { id: 1, num: null },
{ preid: 1, num: 333 },
{ id: 2, num: 333 },
]
只要 preid
等于 id
这个字段,转换为一个新数组,放入 对象里,二级嵌套数组
最终结果
var array = [ {
id: 1, num: null,
array1: [
{ preid: 1, num: 333 }
]
},
{ id: 2, num: 333 },
]
同学,帮你排了个版,去掉了无用的信息。请你抽空学一下 Markdown 排版。就算不是为了问问题,用 Markdown 写技术文档也是极好的。
—— @边城
回答:
const array = [ { id: 1, num: null },
{ preid: 1, num: 333 },
{ id: 2, num: 333 },
]
function makeTree(list) {
// 产生一个映射表,方便从 id 找到节点对象
// 因为有些节点没有 id,会以 undefined 作为键放入 map
// 后面用虚拟的 root 节点替换掉(反正他们都没用)
const dict = new Map(list.map(it => [it.id, it]));
// 做一个空的 root 节点进去,所有没有 preid 的节点都会是它的子节点
const root = {};
dict.set(undefined, root);
list.forEach(it => {
(dict.get(it.preid).array1 ??= []).push(it);
// ^^^^^^^^^^^^^^ 根据 preid 找到其父节点,如果没有 preid,其父节点会是 root
// ^^^^^^^^^^^^^^ 如果还没有 array1 属性,给个初值 []
// ^^^^^^^^^ 把当前节点加到 .array1 里
});
// root 本身是个虚节点,需要的只是它的 array1 这个节点集
return root.array1;
}
const r = makeTree(array);
console.log(JSON.stringify(r));
// [{"id":1,"num":null,"array1":[{"preid":1,"num":333}]},{"id":2,"num":333}]
回答:
受边城大佬的写法启发,优化一下代码
我的思路是:
- 提取第一层,对子项分组
- 遍历第一层组装 array1
function makeTree(list) { const map = new Map();
const root = [];
// 提取第一层节点,分组子项
list.forEach((item) => {
"id" in item
? root.push(item)
: map.has(item.preid)
? map.get(item.preid).push(item)
: map.set(item.preid, [item]);
});
// 遍历父项组装结果
root.forEach((node) => map.has(node.id) && (node.array1 = map.get(node.id)));
return root;
}
// test case
var array = [
{ id: 10, num: 222 },
{ id: 1, num: null },
{ preid: 1, num: 333 },
{ preid: 0, num: 333 },
{ preid: 2, num: 333 },
{ id: 2, num: 333 },
];
const tree = makeTree(array);
console.log(JSON.stringify(tree, null, "\t"));
边城大佬的思路是:
- 先预设好 id2array1 的map
- 同时做分组和组装
写法相较于我的代码优雅很多,但第一次读代码需要绕一绕(个人感觉)
以上是 数组里有多个对象,对象中相同的id 组成一个数组。放在他的子项有啥好的方法吗?求大佬给个最优解决方法 的全部内容, 来源链接: utcz.com/p/935639.html