当孩子有多个父母时,如何向嵌套的 json 对象添加正确的深度值

问题描述 投票:0回答:1

在尝试将深度值添加到嵌套数组中的每个对象时,我遇到了问题。

我面临的具体问题是,当一个对象有多个兄弟姐妹时,深度将应用于第一个而不是其他对象,但我需要每个对象都有一个深度值。

var data = [
  { "title": "meta", "parentids": [] },
  { "title": "instagram", "parentids": ["meta"] },
  { "title": "facebook", "parentids": ["meta"] },
  { "title": "whatsapp", "parentids": ["meta"] },
  { "title": "zuckerberg", "parentids": ["instagram", "facebook"] },
]

// Assign a 'children' property to each object.
data.forEach(o => o.children = [])

// For each object assign a key/object pair
let map = data.reduce((a, o) => (a[o.title] = o, a), {})

// For each 'parentids' in each object in data push this object
data.forEach(o => o.parentids.forEach(pid => map[pid] && map[pid].children.push(o)))

let copyOfData = [...data];

let assignDepth = (arr, depth = 0, index = 0) => {
   if(index < arr.length){
      arr[index].depth = depth;
      if(arr[index].children.length){
         return assignDepth(arr[index].children, depth+1, 0);
      };
      return assignDepth(arr, depth, index+1);
   };
   return;
};

if (copyOfData.length) {
    assignDepth(copyOfData)
    console.log(copyOfData)
}

javascript arrays recursion multidimensional-array depth
1个回答
0
投票

递归的经验法则:用它来探索深度(树),而不是广度(数组)。使用循环来扩大广度。

在这种情况下,您的递归函数会重载以沿数组计数并深入探索。但是使用循环来迭代

children
数组可以节省大量工作——您可以从递归调用签名中删除索引参数。只需在最好的地方使用递归即可:深入探索树。

const data = [
  {title: "meta", parentids: []},
  {title: "instagram", parentids: ["meta"]},
  {title: "facebook", parentids: ["meta"]},
  {title: "whatsapp", parentids: ["meta"]},
  {title: "zuckerberg", parentids: ["instagram", "facebook"]},
];

const titleLookup = Object.fromEntries(
  data.map(e => {
    e.children = [];
    return [e.title, e];
  })
);

for (const o of data) {
  for (const pid of o.parentids) {
    titleLookup[pid].children.push(o);
  }
}

const assignDepth = (arr, depth = 0) => {
  for (const e of arr) {
    assignDepth(e.children, depth + 1);
    e.depth ??= depth;
  }
};

assignDepth(data);
console.log(data);

© www.soinside.com 2019 - 2024. All rights reserved.