【问题标题】:Convert a nested hierarchical array into flattened object将嵌套层次数组转换为展平对象
【发布时间】:2021-08-08 21:56:21
【问题描述】:

我有一个嵌套的 json 数组对象,如下所示

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","items": {"1": {"id": "1","children": ["P1","P2"]}。这很简单,因为我可以使用过滤器功能。但是在此之后,我怎样才能使 P1 和 P2 的孩子变平?

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

一种尝试是

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), []);
};

【问题讨论】:

    标签: javascript arrays ecmascript-6 flatten


    【解决方案1】:

    你可以通过使用一个模式来收集所有具有该模式的嵌套对象。

    这种方法也适用于所有孩子。如果不需要,您可以添加一个检查并省略没有孩子的孩子。

    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; }

    【讨论】:

    • 太好了,非常感谢
    【解决方案2】:

    你可以使用 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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-15
      • 1970-01-01
      • 1970-01-01
      • 2021-11-06
      • 2022-11-24
      相关资源
      最近更新 更多