javascript - 从平面结构和反向制作嵌套对象结构?

标签 javascript arrays algorithm tree flatten

我有一个平面阵列。像这样:

const inputArray = [
  {
    path: '1',
    id: '1'
  },
  {
    path: '2',
    id: '2'
  },
  {
    path: '3',
    id: '3'
  },
  {
    path: '3.4',
    id: '4'
  },
  {
    path: '3.5',
    id: '5'
  },
  {
    path: '3.4.6',
    id: '6'
  },
  {
    path: '3.4.7',
    id: '7'
  },
  {
    path: '8',
    id: '8'
  },
]

其中 path 是元素的唯一路径(按 id)。例如,path: '3.5' 表示此对象是具有 id: '3' 的对象的子对象。 path: '3.4.6'path: '3.4' 的子级。 我想将它们收集到嵌套结构中。所以结果应该是这样的。

const result = [
  {
    path: '1',
    id: '1',
    children: []
  },
  {
    path: '2',
    id: '2',
    children: []
  },
  {
    path: '3',
    id: '3',
    children: [
      {
        path: '3.4',
        id: '4',
        children: [
           {
            path: '3.4.6',
            id: '6',
            children: []
          },
          {
            path: '3.4.7',
            id: '7',
            children: []
          },
        ]
      },
      {
        path: '3.5',
        id: '5',
        children: []
      },
    ]
  },
  {
    path: '8',
    id: '8',
    children: []
  },
]

而且我还需要第二种算法将它们从嵌套结构转换回平面结构。可以给点广告建议吗?

更新:数据未排序。 Here是我的尝试,但是代码太多,在某些情况下会失败。我觉得应该有更好的方法来做到这一点。

最佳答案

使用Array.reduce , Array.findIndex , Array.pushArray.shift

转换为树

  • 假设输入数组按路径排序,否则,您不会对inputArray.sort((a,b) => a.path - b.path);
  • 缩减数组形成树
  • 通过拆分路径并从中创建数字数组来创建层次结构数组
  • 创建一个函数 addChildren,它将接受 3 个输入
    • a -> 将插入对象的父对象(数组)
    • c -> 需要插入的对象
    • t -> 需要插入的对象层次数组
  • 函数采用 t 的第一个值,如果它在层次结构中是最后一个,则 这意味着 a 是对象的有效占位符。因此, 把它推到那里。如果还有剩余值,则找到 通过匹配 id 从数组中获取占位符。现在,再次调用 带有a 的函数将成为匹配对象children 数组, c 保持不变,t 将是剩余的层次结构数组。

const inputArray = [{path:'1',id:'1'},{path:'2',id:'2'},{path:'3',id:'3'},{path:'3.4',id:'4'},{path:'3.5',id:'5'},{path:'3.4.6',id:'6'},{path:'3.4.7',id:'7'},{path:'8',id:'8'}];

const result = inputArray.reduce((a,c) => {
  let t = c.path.split(".").map(Number);
  addChildren(a,c,t);
  return a;
}, []);

function addChildren(a, c, t) {
  let val = t.shift();
  if(!t.length) {
    a.push({...c, children : []});
  } else {
    var i = a.findIndex(({id}) => Number(id) === val);
    addChildren(a[i].children, c, t);
  }
}
console.log(result);

压平树

  • 创建一个接受 2 个输入的函数
    • a -> 输入数组(子数组)
    • r -> 结果数组
  • 函数遍历输入数组并将对象压入 结果数组并检查是否有任何 child ,如果是,则调用该函数 也适合 child

var inputArray = [{path:'1',id:'1',children:[]},{path:'2',id:'2',children:[]},{path:'3',id:'3',children:[{path:'3.4',id:'4',children:[{path:'3.4.6',id:'6',children:[]},{path:'3.4.7',id:'7',children:[]},]},{path:'3.5',id:'5',children:[]},]},{path:'8',id:'8',children:[]},];

function flattenArray(a, r) {
  a.forEach(({children, ...rest}) => {
    r.push(rest);
    if(children) flattenArray(children, r)
  });
}
var result = [];
flattenArray(inputArray, result);
console.log(result);

关于javascript - 从平面结构和反向制作嵌套对象结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50736351/

相关文章:

javascript - Jquery ajax 请求完成但 Axios 失败

javascript - 检测 AJAX 请求调用的 Iframe 滚动事件

Java:如何根据对象的类型动态创建指定类型的数组?

Java:使用 charAt 将输入与 char 数组进行比较

c - 二分查找递归的问题

javascript - 如何在 bootstrap 4 toggle 中隐藏/显示效果倍数

javascript - Bootstrap 中的弹出窗口

php - 内爆对象数组中给定名称的所有属性 - PHP

algorithm - BFS 可以用来识别最远的顶点吗?

algorithm - 以最低成本合并 n 个硬币以创建一个硬币