JavaScript:将Json数据数组更改为新格式 [英] JavaScript: Change Json data array into new format
问题描述
我正在尝试使用需要以多种方式更改的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屋!