JavaScript:将Json数据数组更改为新格式 [英] JavaScript: Change Json data array into new format

查看:84
本文介绍了JavaScript:将Json数据数组更改为新格式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用需要以多种方式更改的json数据.

I am trying to work with a json data which needs to be changed in many ways.

我当前的json数据如下:

My current json data is following:

{
  "file1": {
    "function1": {
      "calls": {
        "105:4": {
          "file": "file2",
          "function": "function5"
        },
        "106:4": {
          "file": "file2",
          "function": "function6"
        }
      },
      "lines1": {
        "123": "102:0",
        "456": "105:8"
      },
      "lines2": {
        "102:0": [
          "102:0"
        ],
        "105:4": [
          "106:4",
          "107:1"
        ],
        "106:4": [
          "107:1"
        ]
      }
    }
  }
}

但是我想要以下数据:

{
  "name": "program",
  "children": [
    {
      "name": "file1",
      "children": [
        {
          "name": "function1",
          "calls": [
            {
              "line": 105,
              "file": "file2",
              "function": "function5"
            },
            {
              "line": 106,
              "file": "file2",
              "function": "function6"
            }
          ],
          "lines1": [
            102,
            105
          ],
          "lines2": [
            [
              102,
              102
            ],
            [
              105,
              106,
              107
            ],
            [
              106,
              107
            ]
          ],
          "group": 1
        }
      ],
      "group": 1
    }
  ],
  "group": 0
}

这里,文件和功能的数量更多.名字的值是用户定义的.组信息取决于父子.每个文件将具有一个组升序组号,并且文件内的所有功能也将具有相同的组号.对于行的值,采用:的第一部分(104:4变为104).

Here, number of files and functions are more. The value of first name is user defined. The group information is depend on the parent-child. Each file will have a group ascending group number and all the functions inside the file will also have the same group number. For the values for lines the first part before : are taken (104:4 becomes 104).

到目前为止,我已经尝试使用以下代码,该代码不完整并且无法正确处理组信息.

I have tried with following code so far, which is incomplete and not handling group information correctly.

function build(data) {
    return Object.entries(data).reduce((r, [key, value], idx) => {
      const obj = {
        name: 'program',
        children: [],
        group: 0,
        lines: []
      }

      if (key !== 'lines2) {
        obj.name = key;
        obj.children = build(value)
          if(!(key.includes(":")))
          obj.group = idx + 1;
      } else {
        if (!obj.lines) obj.lines = [];
        Object.entries(value).forEach(([k, v]) => {
          obj.lines.push([k, ...v].map(e => e.split(':').shift()))
        })
      }

      r.push(obj)
      return r;
    }, [])
  }

  const result = build(data);
  console.log(result);

如果您能帮助我,我将不胜感激.预先感谢您的宝贵时间.

I would really appreciate if you can help me out. Thanks in advance for your time.

推荐答案

假定您的输入的结构如您的问题所示一致地定义(即,不需要安全检查"等),那么您可以采用结合使用 Object.entries() Array.map() 扩展语法,如下所示.

Assuming the structure of your input is consistenly defined as shown in your question (ie, that no "saftey checks" are needed, etc), then you could approach this using a combination of Object.entries(), Array.map() and spread syntax as shown below.

有关如何实现此目标的详细信息,请参见此代码段中的内联文档:

See inline documentation in this code snippet for details on how to achieve that:

function transformData(data, programName) {

  /* Define local parse helper to extract number from NUMBER:STRING format */    
  const parseHelper = (str) => Number.parseInt(str.split(':')[0]);
      
  /* Define local parse helper to extract group number from STRINGNUMBER 
  format */    
  const parseGroup = (str) => Number.parseInt(str.replace(/^[a-z]+/,""))
      
  /* Create a root object with specified program name */
  return {
    name : programName,
    
    /* Iterate each file name and object entry of input */
    children : Object.entries(input).map(([fileName, fileObject]) => {

      /* Iterate function name and object of current file object */
      const fileChildren = Object.entries(fileObject)
        .map(([functionName, functionObject]) => {

        /* Iterate function name and object of current file object */
        const lines = Object.entries(functionObject)
          .reduce((target, [functionKey, functionValue]) => {

            if(functionKey === "calls") {

              /* If function key is calls, interpret this value as data to be
              transformed to desired calls object shape */
              const calls = Object.entries(functionValue)
                .map(([callKey, callObject]) => {

                return {
                  line : parseHelper(callKey),
                  file : callObject['file'],
                  function : callObject['function']
                }
              });
              
              /* Inject calls object into lines result */
              return {
                ...target,
                calls
              };
            }
            else {

              /* Otherwise, interpret this value as data to be transformed to 
                 desired lines object shape */
              const lineValues = Object.entries(functionValue)
                .map(([key, value]) => {

                /* If value is an array, map key/value pair to a nested array
                   in resulting linesValues array */
                return Array.isArray(value) ? [key, ...value]
                 .map(parseHelper) : parseHelper(value)
              })

              /* Inject line values into function key of result */
              return {
                ...target,
                [functionKey] : lineValues
              }
            }

        }, {});
        
        /* Inject lines into function result */
        return {
          name : functionName,
          ...lines,
          group : parseGroup(functionName)
        }
      });

      /* Map file object to name/children pairing */
      return { 
        name : fileName,
        children : fileChildren,
          group : parseGroup(fileName)
      }
    }),
    
    group : 0
  }
}

const input = {
  "file1": {
    "function1": {
      "calls": {
        "105:4": {
          "file": "file2",
          "function": "function5"
        },
        "106:4": {
          "file": "file2",
          "function": "function6"
        }
      },
      "lines1": {
        "123": "102:0",
        "456": "105:8"
      },
      "lines2": {
        "102:0": [
          "102:0"
        ],
        "105:4": [
          "106:4",
          "107:1"
        ],
        "106:4": [
          "107:1"
        ]
      }
    }
  }
};

console.log(transformData(input, "program"))

希望有帮助!

这篇关于JavaScript:将Json数据数组更改为新格式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆