如何将嵌套的 JSON 数据结构简化为地图 JavaScript

mer*_*ilj 5 javascript json data-structures

我已经用循环实现了以下问题的解决方案,但我确信有更好的方法。考虑这个数据结构:

let arr = [
    {
        "id": "000701",
        "status": "No Source Info",
        "sources": []
    },
    {
        "id": "200101",
        "status": "Good",
        "sources": [
            {
                "center": "H2",
                "uri": "237.0.1.133",
                "program": 1,
                "status": "Good",
                "state": {
                    "authState": "authorized",
                    "lockState": "locked"
                }
            }
        ]
    },
    {
        "id": "005306",
        "status": "Good",
        "sources": [
            {
                "center": "H1",
                "uri": "237.0.6.5",
                "program": 3,
                "status": "Good",
                "state": {
                    "authState": "authorized",
                    "lockState": "locked"
                }
            },
            {
                "center": "H1",
                "uri": "237.0.6.25",
                "program": 3,
                "status": "Good",
                "state": {
                    "authState": "authorized",
                    "lockState": "locked"
                }
            }
        ]
    }
]
Run Code Online (Sandbox Code Playgroud)

uri我想学习最有效的方法,将其简化为仅包含嵌套数组和state值的键值对的映射sources。最终结果应如下所示:

let stateMap = {
    "237.0.1.133": { "authState": "authorized", "lockState": "locked" },
    "237.0.6.5": { "authState": "authorized", "lockState": "locked" },
    "237.0.6.25": { "authState": "authorized", "lockState": "locked" } 
}
Run Code Online (Sandbox Code Playgroud)

我有一个部分解决方案,它返回每个数组的映射source,但我正在努力将其全部放入一个结构中。

let allStates = arr.reduce((acc, object) => {
    if (object.sources.length) {
        let sourceMap = object.sources.reduce((map, obj) => {
            map[obj.uri] = obj.state
            return map
        }, {})
        acc[acc.length] = sourceMap
        return acc
    }
    // delete all unused keys and somehow flatten the objects?
}, {})
Run Code Online (Sandbox Code Playgroud)

递归是这里的一个选择还是更好的方法?

Rob*_*sen 2

下面的代码首先flatMap对嵌套sources数组执行操作,然后将所有内容缩减为所需的结果对象:

const result = arr.reduce((a, {sources}) => [...a, ...sources], [])
                  .reduce((a, {uri, state}) => ({...a, [uri]: state}), {});
Run Code Online (Sandbox Code Playgroud)

完整片段:

const result = arr.reduce((a, {sources}) => [...a, ...sources], [])
                  .reduce((a, {uri, state}) => ({...a, [uri]: state}), {});
Run Code Online (Sandbox Code Playgroud)