【问题标题】:Convert an array of objects into an array of nested objects js将对象数组转换为嵌套对象数组js
【发布时间】:2020-06-22 18:52:33
【问题描述】:

所以我有一个任务来正确排序文件目录。为简单起见,所有文档和文件都保存为平面数组。作为显示嵌套文件的标识符,我有一个属性 uniqueId,它告诉我什么是父目录。平面数组按 uniqueId 排序,因此每个子元素都在其父元素之后。

这里是一个平面数组的例子:

[{
 id: 1,
 uniqueId: '1',
 name: 'folder1',
 dir: true
},
{
 id: 2,
 uniqueId: '1.2',
 name: 'test1',
 dir: false
},
{
 id: 3,
 uniqueId: '1.2.3',
 name: 'test2'
 dir: false
},
{
 id: 4,
 uniqueId: '1.2.4',
 name: 'test3'
 dir: true
},
{
 id: 3,
 uniqueId: '1.3',
 name: 'test23'
 dir: true
},
{
 id: 1,
 uniqueId: '1.3.1',
 name: 'test6',
 dir: true
},
]

基本上代表文件目录树:

1
  1.2
    1.2.3
    1.2.4
  1.3
    1.3.1

我需要首先显示目录,即具有dir: true 的目录。因此,上面的树会变成:

1
 1.3
    1.3.1
 1.2
    1.2.4
    1.2.3

因此,作为一种解决方案,我决定最好将平面数组转换为嵌套对象,以所需的方式对每个对象的子对象进行排序,然后再次转换为平面数组。这样我的平面数组就会变成这样:

{
 id: 1,
 uniqueId: '1',
 name: 'folder1',
 dir: true
 childs: [
  {
   id: 2,
   uniqueId: '1.2',
   name: 'test1',
   dir: false,
   childs: [
   {
     id: 3,
     uniqueId: '1.2.3',
     name: 'test2'
     dir: false
   },
   {
     id: 4,
     uniqueId: '1.2.4',
     name: 'test3'
     dir: true
   }
 ]},
 {
   id: 3,
   uniqueId: '1.3',
   name: 'test23'
   dir: true,
   childs: [
    {
     id: 1,
     uniqueId: '1.3.1',
     name: 'test23'
     dir: true
    }
  ]
}
}]

我找不到将平面转换为所需嵌套对象的方法。我已经有一个返回当前对象 isChild(parent, objectToCheck) 的子对象的函数。我想最好为此使用某种递归,但我完全被卡住了。

请帮我把它转换成想要的嵌套对象。

也欢迎任何有关对平面数组进行排序的其他方法的建议!也许有更好的方法来对其进行排序,而无需实际转换回来并强制执行?

提前非常感谢!

【问题讨论】:

  • 这些数组元素是否总是按照我们在示例输入中看到的顺序排序?
  • @RahulBhobe 是的,我有一个排序功能可以做到这一点。感谢您提出问题,我会更新我的问题以提及这一点

标签: javascript arrays sorting lodash


【解决方案1】:

您可以直接对数据进行排序,并使用uniqueId 和父值构建一棵树。

const
    input = [{ id: 1, uniqueId: '1', name: 'folder1', dir: true }, { id: 2, uniqueId: '1.2', name: 'test1', dir: false }, { id: 3, uniqueId: '1.2.3', name: 'test2', dir: false }, { id: 4, uniqueId: '1.2.4', name: 'test3', dir: true }, { id: 3, uniqueId: '1.3', name: 'test23', dir: true }, { id: 1, uniqueId: '1.3.1', name: 'test6', dir: true }],
    tree = function (data) {
        var t = {};
        data.forEach(o => {
            const parent = o.uniqueId.split('.').slice(0, -1).join('.');
            Object.assign(t[o.uniqueId] = t[o.uniqueId] || {}, o);
            t[parent] = t[parent] || {};
            t[parent].children = t[parent].children || [];
            t[parent].children.push(t[o.uniqueId]);
        });
        return t[''].children;
    }(input.sort((a, b) => b.dir - a.dir));
   
console.log(tree);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 谢谢!这将是我将平面数组转换为嵌套对象后的第二步。但我的问题是我现在无法将平面数组转换为嵌套对象。
  • 非常感谢。这是一个完美的解决方案! @妮娜
  • 我唯一需要修改的是用t[o.uniqueId] = {...o, childs: t[o.uniqueId] && t[o.uniqueId].childs || []} 替换以下行:Object.assign(t[o.uniqueId] = t[o.uniqueId] || {}, o) 因为 Object.assign 覆盖了现有对象的 childs 属性 t[o.uniqueId]
猜你喜欢
  • 2018-01-04
  • 2021-07-12
  • 2019-04-26
  • 1970-01-01
  • 1970-01-01
  • 2020-01-15
  • 1970-01-01
  • 2015-03-26
  • 2019-01-31
相关资源
最近更新 更多