javascript - 在 JavaScript 中给定路径和元素数组构建自定义对象

标签 javascript arrays json data-manipulation

本质上,我想根据给定的对象数组构建一个新结构。对象有效负载将类似于下面的元素数组。

const data = [
{
  path: [],
  elements: ['Parent A']
},
{
  path: ['Parent A'],
  elements: ['Child A1', 'Child A2', 'Parent B']
},
{
  path: ['Parent A', 'Parent B'],
  elements: ['Child B1', 'Parent C']
},
{
  path: ['Parent A', 'Parent B', 'Parent C'],
  elements: ['Child C1']
},
{
  path: ['Parent D'],
  elements: ['Child D1']
},
]

上面的有效负载将被转换为如下所示的自定义对象。

let newObject =
[
 {
  elem: "",
  children: [
   {
    elem: "Parent A",
    children: [
     {
      elem: "Child A1",
      children: []
     },
     {
      elem: "Child A2",
      children: []
     },
     {
      elem: "Parent B",
      children: [
      {
       elem: "Child B1",
       children: []
      },
      {
       elem: "Parent C",
       children: [
       {
        elem: "Child C1",
        children: []
       }
       ]
      },
      ]
     },
    ]
   }
  ]
 },
 {
  elem: "Parent D",
  children: [
   {
    elem: "Child D1",
    children: []
   }
  ]
 }
]

我考虑过制作一个 map ,在其中为每个元素提供一个已访问的属性(以避免重新创建元素),并采用递归方法来填充潜在的父元素。然而,我目前陷入困境,正在寻找有关我应该使用哪种数据结构/方法的反馈。

我的映射器代码

const stringifyPath = (arr) => {
    return arr.join('>');
}

let elemMap = new Map();

data.forEach(item => {
    const itemPath = stringifyPath(item.path);
    if (!elemMap.get(itemPath)) {
        elemMap.set(itemPath, {
            elements: [],
            visited: false
        })
    }
    elemMap.get(itemPath).elements = [...elemMap.get(itemPath).elements, ...item.elements];
});

这会产生

{
  '' => { elements: [ 'Parent A' ], visited: false },
  'Parent A' => { elements: [ 'Child A1', 'Child A2', 'Parent B' ],
    visited: false },
  'Parent A>Parent B' => { elements: [ 'Child B1', 'Parent C' ], visited: false },
  'Parent A>Parent B>Parent C' => { elements: [ 'Child C1' ], visited: false },
  'Parent D' => { elements: [ 'Child D1' ], visited: false } }

欢迎任何反馈,谢谢!

最佳答案

您可以通过减少为每个嵌套级别查找对象的路径并将新元素推送到找到的对象的子级来减少路径,从而采用直接的方法。

对我来说,存储所有路径是没有意义的,因为构建结构时只需要它们一次。

var data = [{ path: [], elements: ['Parent A'] }, { path: ['Parent A'], elements: ['Child A1', 'Child A2', 'Parent B'] }, { path: ['Parent A', 'Parent B'], elements: ['Child B1', 'Parent C'] }, { path: ['Parent A', 'Parent B', 'Parent C'], elements: ['Child C1'] }, { path: ['Parent D'], elements: ['Child D1'] }],
    result = data.reduce((r, { path, elements }) => {
        path
            .reduce((array, elem) => {
                var temp = array.find(q => q.elem === elem);
                if (!temp) array.push(temp = { elem, children: [] });
                return temp.children;
            }, r)
            .push(...elements.map(elem => ({ elem, children: [] })));
        return r;
    }, []);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

关于javascript - 在 JavaScript 中给定路径和元素数组构建自定义对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60117637/

相关文章:

PHP - 计算多维数组中第一个元素的唯一值

javascript - 将键/值对转换为 json

c# - 在排序数组中找到小于 x 的最大值

javascript - 如何仅在移动设备上添加新按钮导航栏 View (使用 Bootstrap )

javascript - 使用 javascript 解析 formdata 对象

javascript:组合函数和 if 的问题

C *char 指向 char 数组的指针

java.lang.String 无法从 Android 转换为 JSONObject

php - MySQL JSON 数据类型是否不利于数据检索的性能?

javascript - 如何使用 AngularJS 检索外部网站的内容(逐个元素)