数组里有多个对象,对象中相同的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 写技术文档也是极好的。

—— @边城

阅读 2.9k
2 个回答
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}]

边城大佬的写法启发,优化一下代码

我的思路是:

  1. 提取第一层,对子项分组
  2. 遍历第一层组装 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"));

边城大佬的思路是:

  1. 先预设好 id2array1 的map
  2. 同时做分组和组装

写法相较于我的代码优雅很多,但第一次读代码需要绕一绕(个人感觉)

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题