【问题标题】:Trouble with Mapping multilevel JSON object to javascript array将多级 JSON 对象映射到 javascript 数组时遇到问题
【发布时间】:2021-05-05 15:03:08
【问题描述】:

我有一个从 API 返回的 JSON 数据,我想将其转换为数组,但无法将“时间线”类别放入数组中,

示例 JSON:

[{
    "id": 100,
    "key1": 310797,
    "key2": 807874,
    "key3": 24283,
    "key4": 180900,
    "timeline": {
        "createDate": "2021-04-08T22:53:23Z",
        "lastChangeDate": "2021-04-27T12:03:57Z"
    }
},
{
    "id": 101,
    "key1": 310797,
    "key2": 807875,
    "key3": 24284,
    "key4": 180903,
    "timeline": {
        "createDate": "2021-04-04T22:53:23Z",
        "lastChangeDate": "2021-04-24T12:02:57Z"
    },
    {
        ...
    }
]

我正在使用以下 Javascript 尝试将其解析为数组

function convertToArray(json) {
    var headers = Object.keys(json[0]);
    var values = json.map(function(e) {
        return headers.map(function(f) {
            return e[f]
        })
    });
    values.unshift(headers);
    return values
}

这是返回:

[[id, key1, key2, key3, key4, timeline],
[100, 310797, 807874, 24283, 180900, ""],
[101, 310797, 807875, 24284, 180903, ""]]

但是我想要实现的数组是:

[[id, key1, key2, key3, key4, createDate, lastChangeDate],
[100, 310797, 807874, 24283, 180900, 2021-04-08T22:53:23Z, 2021-04-27T12:03:57Z],
[101, 310797, 807875, 24284, 180903, 2021-04-04T22:53:23Z, 2021-04-24T12:02:57Z]]

任何关于如何将“createDate”和“lastChangeDate”映射到数组中的帮助将不胜感激

【问题讨论】:

    标签: javascript arrays json


    【解决方案1】:

    const arr = [
      {
        id: 100,
        key1: 310797,
        key2: 807874,
        key3: 24283,
        key4: 180900,
        timeline: {
          createDate: "2021-04-08T22:53:23Z",
          lastChangeDate: "2021-04-27T12:03:57Z",
        },
      },
      {
        id: 101,
        key1: 310797,
        key2: 807875,
        key3: 24284,
        key4: 180903,
        timeline: {
          createDate: "2021-04-04T22:53:23Z",
          lastChangeDate: "2021-04-24T12:02:57Z",
        },
      },
    ];
    
    // Getting keys
    let keys = [];
    const obj = arr[0];
    Object.entries(obj).forEach((entry) => {
      const [key, value] = entry;
      if (typeof value === "object") keys.push(...Object.keys(value));
      else keys.push(key);
    });
    
    // Getting values
    const values = arr.map((obj) => {
      let temp = [];
      for (let key in obj) {
        if (typeof obj[key] === `object`) temp.push(...Object.values(obj[key]));
        else temp.push(obj[key]);
      }
      return temp;
    });
    
    result = [keys, ...values];
    
    console.log(result);

    【讨论】:

      【解决方案2】:

      这是一个从对象结构中递归收集键和值的解决方案:

      const arr = [
        {
          id: 100,
          key1: 310797,
          key2: 807874,
          key3: 24283,
          key4: 180900,
          timeline: {
            createDate: "2021-04-08T22:53:23Z",
            lastChangeDate: "2021-04-27T12:03:57Z",
            TZ: {TZname: "GMT", TZoffset: 0} // extended example: third level object
          },
        },
        {
          id: 101,
          key1: 310797,
          key2: 807875,
          key3: 24284,
          key4: 180903,
          timeline: {
            createDate: "2021-04-04T22:53:23Z",
            lastChangeDate: "2021-04-24T12:02:57Z",
          },
        },
      ];
      
      // helper function getE : "get entry"
      const getE=(j,ar=[],ge)=> // gets keys or values, dependent on `j`
        ge=c=>{Object.entries(c).forEach(e=>{
           if(typeof e[1] === "object") ge(e[1])
           else ar.push(e[j]);
        }); return ar};
        
       const res=arr.reduce((a,c,i)=>( !i && a.push(getE(0)(c)), a.push(getE(1)(c)), a),[] );
      
      console.log(res)

      该操作发生在函数getE() 内:getE(j,ar=[],ge) 设置了一个范围,在该范围内定义了j(要返回的数量)和ar(一个用于收集的数组)。

      getE(j) 只有一个必需 参数:j,表示要返回的条目部分:0 用于键,1 用于值。它返回函数 (ge(c)),它将在最初给定的对象 c 上递归调用自身:

      ge(c) 内,表达式Object.entries(c).forEach() 遍历c 的所有条目并将

      • 要么使用条目ge(e[1]) 的当前值部分调用自身,
        if (typeof e[1] === "object")true

      • 或者将条目的j-th 部分(e[j])添加到集合数组ar

      ge(c) 返回集合数组ar

      【讨论】:

      • 感谢您的回答以及您对它的工作原理以及我出错的地方的清晰描述。这是完美的工作
      【解决方案3】:

      我将时间线键放在一个集合中,可以在映射行数据时用作查找,并且可以轻松地与标题的其他键合并

      const timeKeys = new Set(Object.keys(data[0].timeline));
      
      const headers  = Object.keys(data[0])
                         .filter(k => k!=='timeline')
                         .concat(...timeKeys);
      
      const values = data.map(o => {
          return headers.map(k => {
            return timeKeys.has(k) ? o.timeline[k] : o[k];      
          });
      });
      
      const res = [headers , ...values];
      
      
      console.log(res)
      <script>
      const data=[{id:100,key1:310797,key2:807874,key3:24283,key4:180900,timeline:{createDate:"2021-04-08T22:53:23Z",lastChangeDate:"2021-04-27T12:03:57Z"}},{id:101,key1:310797,key2:807875,key3:24284,key4:180903,timeline:{createDate:"2021-04-04T22:53:23Z",lastChangeDate:"2021-04-24T12:02:57Z"}}];
      </script>

      【讨论】:

        猜你喜欢
        • 2020-11-09
        • 2012-02-06
        • 2019-11-26
        • 2018-08-28
        • 2019-05-27
        • 2017-06-26
        • 2021-01-04
        • 2015-05-16
        • 1970-01-01
        相关资源
        最近更新 更多