【问题标题】:How to reduce nested JSON data structure into a map JavaScript如何将嵌套的 JSON 数据结构简化为地图 JavaScript
【发布时间】:2018-08-17 04:54:46
【问题描述】:

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

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"
                }
            }
        ]
    }
]

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

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

我有一个部分解决方案,它返回每个 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?
}, {})

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

【问题讨论】:

    标签: javascript json data-structures


    【解决方案1】:

    下面的代码首先对嵌套的sources 数组执行flatMap 操作,然后将所有内容归约为您想要的结果对象:

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

    完成sn-p:

    const 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"
            }
          }
        ]
      }
    ];
    
    const result = arr.reduce((a, {sources}) => [...a, ...sources], [])
                      .reduce((a, {uri, state}) => ({...a, [uri]: state}), {});
    
    console.log(result)

    【讨论】:

      【解决方案2】:

      您可以减少外部数组并迭代 sources 并将对象更新为结果集。

      var data = [{ 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" } }] }],
          stateMap = data.reduce(
              (o, { sources }) => (sources.forEach(({ uri, state }) => o[uri] = state), o),
              Object.create(null)
          );
      
      console.log(stateMap);
      .as-console-wrapper { max-height: 100% !important; top: 0; }

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

      不,因为您只有一个嵌套级别。

      【讨论】:

        【解决方案3】:

        你可以使用嵌套reduce从列表中的项目获取uri映射,其他用于获取源映射的值。

        const mappedArray = arr.reduce((acc, item) => ({
          ...acc,
          ...item.sources.reduce((accSource, itemSource) => ({
            ...accSource,
            [itemSource.uri]: itemSource.state,
          }), {})
        }), {})
        

        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"
                        }
                    }
                ]
            }
        ]
        
        
        const mappedArray = arr.reduce((acc, item) => ({
          ...acc,
          ...item.sources.reduce((accSource, itemSource) => ({
            ...accSource,
            [itemSource.uri]: itemSource.state,
          }), {})
        }), {})
        
        console.log(mappedArray)

        【讨论】:

          猜你喜欢
          • 2020-03-07
          • 2021-11-19
          • 1970-01-01
          • 2020-12-14
          • 2020-06-21
          • 2015-01-15
          • 2021-08-26
          • 2021-04-13
          • 1970-01-01
          相关资源
          最近更新 更多