简体   繁体   English

Javascript - 将嵌套对象转换为项目数组

[英]Javascript - Convert Nested Object to Array of items

I have a object which looks like this: 我有一个看起来像这样的对象:

[
  {
    "id": 1,
    "name": "Electronics",
    "path": "Electronics",
    "children": [
      {
        "id": 2,
        "name": "Laptops & PC",
        "path": "Electronics > Laptops & PC",
        "children": []
      },
      {
        "id": 7,
        "name": "Phones & Accessories",
        "path": "Electronics > Phones & Accessories",
        "children": [
          {
            "id": 8,
            "name": "Smartphones",
            "path": "Electronics > Phones & Accessories > Smartphones",
            "children": [
              {
                "id": 9,
                "name": "Android",
                "path": "Electronics > Phones & Accessories > Smartphones > Android",
                "children": []
              },
              {
                "id": 10,
                "name": "iOS",
                "path": "Electronics > Phones & Accessories > Smartphones > iOS",
                "children": []
              }
            ]
          }
        ]
      }
    ]
  },
  {
    "id": 11,
    "name": "Software",
    "path": "Software",
    "children": []
  }
]

And I wanted to convert it to something like this: 我想把它转换成这样的东西:

[
  {header: 'Electronics'},
  {name: 'Laptops & PC', group: 'Electronics', id: 2},
  {name: 'Phones & Accessories', group: 'Electronics', id: 7},
  {name: 'Smartphones', group: 'Phones & Accessories', id: 8},
  {name: 'Android', group: 'Smartphones', id: 9},
  {name: 'iOS', group: 'Smartphones', id: 10},
  {divider: true},
  {name: 'Software', group: 'Software', id: 11}
]

Basically, 基本上,

  • If a root element has children, it should be converted as header . 如果根元素具有子元素,则应将其转换为header
  • All the elements should have its parent name as group 所有元素都应将其父名称作为group
  • When finished with one root element, It needs to insert {divider: true} before proceeding to the next. 完成一个根元素后,需要在继续下一个之前插入{divider: true} (If it's the last root element, do not insert {divider: true} (如果它是最后一个根元素,请不要插入{divider: true}

While I was able to find lots of Hierarchical to JSON solutions on stackoverflow, I was not able to reverse engineer those solutions. 虽然我能够在stackoverflow上找到许多Hierarchical to JSON解决方案,但我无法对这些解决方案进行逆向工程。

Can somebody please help me? 有人能帮帮我吗?

You could take an iterative and recursive approach by checking header keeping the corresponding divider and iterate children. 您可以通过检查标头保持相应的分隔符并迭代子节点来采用迭代和递归方法。

Then you need to add the standard object for any item. 然后,您需要为任何项添加标准对象。

The recursive callback uses a closure over the group. 递归回调在组上使用闭包。 if not set, the group is a root item. 如果未设置,则该组是根项目。

 function getParts(array) { var result = []; array.forEach(function iter(group) { return function ({ id, name, children }, i, { length }) { if (!group && children.length) { result.push({ header: name }); } if (group || !children.length) { result.push({ name, group: group || name, id }); } children.forEach(iter(name)); if (!group && i + 1 !== length) { result.push({ divider: true }); } }; }('')); return result; } var data = [{ id: 1, name: "Electronics", path: "Electronics", children: [{ id: 2, name: "Laptops & PC", path: "Electronics > Laptops & PC", children: [] }, { id: 7, name: "Phones & Accessories", path: "Electronics > Phones & Accessories", children: [{ id: 8, name: "Smartphones", path: "Electronics > Phones & Accessories > Smartphones", children: [{ id: 9, name: "Android", path: "Electronics > Phones & Accessories > Smartphones > Android", children: [] }, { id: 10, name: "iOS", path: "Electronics > Phones & Accessories > Smartphones > iOS", children: [] }] }] }] }, { id: 11, name: "Software", path: "Software", children: [] }, { id: 11, name: "Software", path: "Software", children: [] }, { id: 11, name: "Software", path: "Software", children: [] }], result = getParts(data); console.log(result); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

Here's a recursive approach using array.reduce and the spread operator ( ... ) to flatten lists as you move through the data, and a separate helper function to take care of non-headers: 这是一个递归方法,使用array.reduce和扩展运算符( ... )在移动数据时展平列表,以及一个单独的辅助函数来处理非标题:

 const flatten = data => data.reduce((a, e, i) => { if (e.children.length) { a.push({header: e.name}); a.push(...flattenR(e.children, e.name)); } else { a.push({name: e.name, group: e.name, id: e.id}); } if (i < data.length - 1) { a.push({divider: true}); } return a; }, []) ; const flattenR = (data, grp) => data.reduce((a, e) => { a.push({name: e.name, group: grp, id: e.id}); a.push(...flattenR(e.children, e.name)); return a; }, []) ; const data = [ { "id": 1, "name": "Electronics", "path": "Electronics", "children": [ { "id": 2, "name": "Laptops & PC", "path": "Electronics > Laptops & PC", "children": [] }, { "id": 7, "name": "Phones & Accessories", "path": "Electronics > Phones & Accessories", "children": [ { "id": 8, "name": "Smartphones", "path": "Electronics > Phones & Accessories > Smartphones", "children": [ { "id": 9, "name": "Android", "path": "Electronics > Phones & Accessories > Smartphones > Android", "children": [] }, { "id": 10, "name": "iOS", "path": "Electronics > Phones & Accessories > Smartphones > iOS", "children": [] } ] } ] } ] }, { "id": 11, "name": "Software", "path": "Software", "children": [] } ]; console.log(flatten(data)); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM