将嵌套的分层数组转换为扁平化 object

Convert a nested hierarchical array into flattened object

我有一个嵌套的 json 数组 object 如下所示

var inputData = [
  {
    "id": "P1",
    "parentTopicId": null,
    "title": "demo title 1",
    "children": [
      {
        "id": "P1-Child1",
        "parentTopicId": "P1",
        "title": "demo title a",
        "children": [
          {
            "id": "id1.1",
            "parentTopicId": "P1Child1",
            "title": "some demo title b",
            "children": [
              {
                "id": "id1.1.1",
                "parentTopicId": "id1.1",
                "title": "demo title",
                "children": []
              }
            ]
          }
        ]
      },
      {
        "id": "P1-Child2",
        "parentTopicId": "P1",
        "title": "some title 2",
        "children": [
          {
            "id": "id1.2",
            "parentTopicId": "P1-Child2",
            "title": "demo titlename",
            "children": []
          }
        ]
      }
    ]
  },
  {
    "id": "P2",
    "parentTopicId": null,
    "title": "Example Title B",
    "children": [
      {
        "id": "P2-Child1",
        "parentTopicId": "P2",
        "title": "example title b2",
        "children": [
          {
            "id": "id2.1",
            "parentTopicId": "P2-Child1",
            "title": "demo title",
            "children": [
              {
                "id": "id2.1.1",
                "parentTopicId": "id2.1",
                "title": "demo titlename",
                "children": []
              }
            ]
          }
        ]
      }
    ]
  }
]

我想要的输出是:

{
 "rootId": "1",
  "items": {
    "1": {
      "id": "1",
      "children": [
        "P1",
        "P2"
      ],
      "hasChildren": true,
      "data": {
        "title": "root"
      }
    },
    "P1": {
      "id": "P1",
      "children": [
        "P1-Child1",
        "P1-Child2"
      ],
      "hasChildren": true,
      "data": {
        "title": "demo title a"
      }
    },
    "P2": {
      "id": "P2",
      "children": [
        "P2-Child1"
      ],
      "hasChildren": true,
      "data": {
        "title": "demo"
      }
    },
    "P1-Child1": {
      "id": "P1-Child1",
      "hasChildren": true,
      "children": [
        "id1.1.1"
      ],
      "data": {
        "title": "demo title"
      }
    },
    "P1-Child2": {
      "id": "P1-Child2",
      "children": [
        "id1.2"
      ],
      "hasChildren": true,
      "data": {
        "title": "demo titlename"
      }
    },
    "P2-Child1": {
      "id": "P2-Child1",
      "children": [
        "id2.1.1"
      ],
      "hasChildren": true,
      "data": {
        "title": "demo titlename"
      }
    }
  }
}

我不确定如何将输入数据准确地转换为我需要的格式。关于如何展平 json 数组有什么建议吗?

我需要先过滤 parentTopicIds 为 null 的输入数组,以便我可以将它们放在 items -> 1-> children 数组中。 {“rootId”:“1”,“项目”:{“1”:{“id”:“1”,“children”:[“P1”,“P2”]}。这非常简单,因为我可以使用过滤器功能。但是在这之后,我怎样才能把 P1 和 P2 的 children 弄平呢?

我找到了一些非常简单的扁平化数组示例,但不符合我的要求

一个尝试是

var outputData ={"rootId": "1","items": {"1": {"children":[]}}};

inputData.filter((item) => {
//first push all nodes whose parentTopicId is null
 if(item.parentTopicId == null) {
    outputData.items["1"]["children"].push(item.id);
    console.log(flatten(item.children)); // this does not provide the required result 
  }
});

function flatten(arr) {
    return arr.reduce((acc, cur) => acc.concat(Array.isArray(cur) ? flatten(cur) : cur), []);
};

您可以通过使用一种模式来收集所有嵌套 object 的模式。

这种方法也采用所有 children。如果不需要,您可以添加一个检查并在没有 children 的情况下省略 children。

const
    flat = ({ id, title, children }) => ({
        [id]: {
            id,
            children: children.map(({ id }) => id),
            hasChildren: !!children.length,
            data: { title }
        },
        ...Object.assign({}, ...children.map(flat))
    }),
    data = { id: "null", title: "root", children: [{ id: "P1", parentTopicId: null, title: "demo title 1", children: [{ id: "P1-Child1", parentTopicId: "P1", title: "demo title a", children: [{ id: "id1.1", parentTopicId: "P1Child1", title: "some demo title b", children: [{ id: "id1.1.1", parentTopicId: "id1.1", title: "demo title", children: [] }] }] }, { id: "P1-Child2", parentTopicId: "P1", title: "some title 2", children: [{ id: "id1.2", parentTopicId: "P1-Child2", title: "demo titlename", children: [] }] }] }, { id: "P2", parentTopicId: null, title: "Example Title B", children: [{ id: "P2-Child1", parentTopicId: "P2", title: "example title b2", children: [{ id: "id2.1", parentTopicId: "P2-Child1", title: "demo title", children: [{ id: "id2.1.1", parentTopicId: "id2.1", title: "demo titlename", children: [] }] }] }] }] },
    result = flat(data);

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

你可以使用 normalizr npm 包。

import { normalize, schema } from 'normalizr';

const user = new schema.Entity('users');

const comment = new schema.Entity('comments', {
commenter: user  
});

const article = new schema.Entity('articles', {
author: user,
comments: [comment]
});

const normalizedData = normalize(originalData, article);

输出:

{
result: "123",
 entities: {
  "articles": {
   "123": {
    id: "123",
    author: "1",
    title: "My awesome blog post",
    comments: [ "324" ]
  }
},
"users": {
  "1": { "id": "1", "name": "Paul" },
  "2": { "id": "2", "name": "Nicole" }
},
"comments": {
  "324": { id: "324", "commenter": "2" }
}

} }

要了解更多信息,请阅读文档 https://github.com/paularmstrong/normalizr