将对象数组转换为嵌套树结构

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

我有一个如下所示的模拟JSON:

const apiData = [{
        "id": 1,
        "label": "List item 1",
        "parent_id": 0
    },
    {
        "id": 5,
        "label": "List item 1",
        "parent_id": 1
    },
    {
        "id": 6,
        "label": "List item 1",
        "parent_id": 1
    },
    {
        "id": 7,
        "label": "List item 1",
        "parent_id": 1
    },
    {
        "id": 8,
        "label": "List item 1",
        "parent_id": 1
    },
    {
        "id": 9,
        "label": "List item 1",
        "parent_id": 8
    },
    {
        "id": 10,
        "label": "List item 1",
        "parent_id": 8
    },
    {
        "id": 2,
        "label": "List item 1",
        "parent_id": 0
    }
]

并且我需要将其转换为以下内容:

[{
        "id": 1,
        "label": "List item 1",
        "parent_id": 0,
        "children": [{
                "id": 5,
                "label": "List item 1",
                "parent_id": 1
            },
            {
                "id": 6,
                "label": "List item 1",
                "parent_id": 1
            },
            {
                "id": 7,
                "label": "List item 1",
                "parent_id": 1
            },
            {
                "id": 8,
                "label": "List item 1",
                "parent_id": 1,
                "children": [{
                        "id": 9,
                        "label": "List item 1",
                        "parent_id": 8
                    },
                    {
                        "id": 10,
                        "label": "List item 1",
                        "parent_id": 8
                    }
                ]
            }

        ]
    },
    {
        "id": 2,
        "label": "List item 1",
        "parent_id": 0
    }
]

我们需要进行更改的条件如下:如果对应于特定的id,则如果我们具有parent_id,则需要在单个对象中添加一个属性children,并将值作为匹配的parent_id对象的数组放置。

我曾尝试为此编写代码,但距离很近,但无法前进。

请提出建议。

我的代码:

const apiData = [
{'id': 1, 'label': 'List item 1', 'parent_id' : 0 },
{'id': 5, 'label': 'List item 1', 'parent_id' : 1 },
{'id': 6, 'label': 'List item 1', 'parent_id' : 1 },
{'id': 7, 'label': 'List item 1', 'parent_id' : 1 },
{'id': 8, 'label': 'List item 1', 'parent_id' : 1},
{'id': 9, 'label': 'List item 1', 'parent_id' : 8 },
{'id': 10, 'label': 'List item 1', 'parent_id' : 8 },
{'id': 2, 'label': 'List item 1', 'parent_id' : 0 },
];

function compare(a, b) {
  const idA = a.id;
  const idB = b.id;
  let comparison = 0;
  comparison = idA > idB ? 1 : (idA < idB ? -1 : 0);
  return comparison;
}

const sortedApiData = apiData.sort(compare);
const newSortedApiData = [...sortedApiData];
let a = []; 


for(let i = 0; i < sortedApiData.length ; i++){
  for(let j = 0 ; j < sortedApiData.length ; j++){
     if(i === j){
       continue;
     }
     else{
       if(sortedApiData[i].id === sortedApiData[j].parent_id){
         a.push(sortedApiData[j]);

       }
     }
  }

}

console.log(a);

javascript arrays tree javascript-objects
1个回答
0
投票

您可以通过遍历数组一次并将节点分配给包含ID的节点的对象,并根据需要创建子数组来构建结果树。

[构建树后,假设数据格式正确,并且树中不存在至少一个父ID不存在的节点(在您的数据集中,没有这样的id: "0"节点),请返回该节点的子节点。仅当每个级别应以特定方式排序时才需要排序。

如果数据格式不正确,会有点复杂;在这种情况下,结果应该是每个引用不存在的父级的节点的合并子级,但是在动机出现之前,我将忽略它。

const unflatten = data => {
  const nodes = data.sort((a, b) => a.id - b.id)
    .reduce((a, e) => {
      a[e.id] = a[e.id] || e;
      a[e.parent_id] = a[e.parent_id] || {};
      const parent = a[e.parent_id];
      parent.children = parent.children || [];
      parent.children.push(e);
      return a;
    }, {})
  ;
  return Object.values(nodes)
    .find(e => e.id === undefined).children;
};

const apiData = [{
    "id": 1,
    "label": "List item 1",
    "parent_id": 0
  },
  {
    "id": 9,
    "label": "List item 1",
    "parent_id": 8
  },
  {
    "id": 8,
    "label": "List item 1",
    "parent_id": 1
  },
  {
    "id": 5,
    "label": "List item 1",
    "parent_id": 1
  },
  {
    "id": 6,
    "label": "List item 1",
    "parent_id": 1
  },
  {
    "id": 7,
    "label": "List item 1",
    "parent_id": 1
  },
  {
    "id": 10,
    "label": "List item 1",
    "parent_id": 8
  },
  {
    "id": 2,
    "label": "List item 1",
    "parent_id": 0
  }
];

const expected = [{
    "id": 1,
    "label": "List item 1",
    "parent_id": 0,
    "children": [{
        "id": 5,
        "label": "List item 1",
        "parent_id": 1
      },
      {
        "id": 6,
        "label": "List item 1",
        "parent_id": 1
      },
      {
        "id": 7,
        "label": "List item 1",
        "parent_id": 1
      },
      {
        "id": 8,
        "label": "List item 1",
        "parent_id": 1,
        "children": [{
            "id": 9,
            "label": "List item 1",
            "parent_id": 8
          },
          {
            "id": 10,
            "label": "List item 1",
            "parent_id": 8
          }
        ]
      }

    ]
  },
  {
    "id": 2,
    "label": "List item 1",
    "parent_id": 0
  }
];

const unflattened = unflatten(apiData);
console.log(unflattened);
console.log(JSON.stringify(unflattened) === JSON.stringify(expected));
© www.soinside.com 2019 - 2024. All rights reserved.