【发布时间】:2020-12-02 12:03:14
【问题描述】:
我有一个嵌套的 json 数据,其中每个父级都有一个数组或对象作为子级,我尝试了一种简单的方法来迭代 json 数据以获取键:值形式,但代码的复杂性也不是最优的作为可读性。有人可以提出一种方法来降低这个复杂性以获得所需的输出吗?
所需的输出是一个对象数组,其中每个对象都有一个键和一个值。键名是有效载荷中键的值,前面是它的父名称,按照点表示法。此外,我们的主要约束是我们不确定哪个子元素可以进一步嵌套。有没有办法可以避免嵌套这么多循环来访问子元素?
这是由嵌套对象和数组组成的 json 有效负载(数据):
[{
"id": {
"no": null,
"uid": null,
"dataBody": {
"area": "Universe",
"place": "LMN",
"information1": [{
"code": "abc",
"group": "xyz",
"data": [{
"definition": {
"type": "up",
"features": {
"featurekey": "ABC",
"featureValues": null
},
"mandatory": true,
},
"cost": {
"currency": "USD",
"value": 1,
}
},
{
"definition": {
"type": "down",
"mandatory": true,
},
"cost": "100"
},
{
"definition": {
"type": "left",
"value": null,
"mandatory": true,
},
"cost": false
}
],
}],
"hobby": {
"indoor": false,
"outdoor": true,
},
"petName": "Tiger",
},
"details": "detail",
"phone": "contact"
}
}]
代码:
const payload = data[0]
const dataBody = payload["id"]["dataBody"]
const answer =[]
// adds child of id which are not an object like no,uid,details,phone gets added in key:value pair
for(let keys in payload["id"]){
if(keys != "dataBody"){
answer.push({"ref":`${keys}`,"value":payload["id"][keys]})
}
}
for(let keys in dataBody){
if(keys!="information" && keys!="hobby"){
answer.push({"ref":`dataBody.${keys}`,"value":dataBody[keys]})
}
}
const information1 = dataBody["information1"]
const hobby = dataBody["hobby"]
for(let keys in hobby){
answer.push({"ref":`hobby.${keys}`,"value":hobby[keys]})
}
const object ={} // definition and cost
for(let keys=0; keys<information1.length;keys++){
const infoValue = keys + 1
const temp = []
for(let infoParameters in information1[keys]){
if(infoParameters != "data"){
answer.push({"ref":`info${infoValue}.${infoParameters}`,"value":information1[keys][infoParameters]})
} else {
const data = information1[keys]["data"]
for(let i=0;i<data.length;i++){
temp.push(data[i])
}
}
}
object[keys]=temp
}
let counter = 0
for(const keys in object){
const dfValues = object[keys]
counter = counter + 1
for(let i=0;i<dfValues.length;i++){
const definition = dfValues[i]["definition"]
const cost = dfValues[i]["cost"]
for(const fdValues in definition){
if(fdValues === "features"){
for(let featureValues in definition[fdValues]){ // maybe bad logic, need to refin
answer.push({"ref":`info${counter}.df${counter}.definition${i+1}.${fdValues}.${featureValues}`, "val": definition[fdValues][featureValues]})
}
} else {
answer.push({"ref":`info${counter}.df${counter}.definition${i+1}.${fdValues}`, "val": definition[fdValues]})
}
}
if(typeof(cost) === "object"){
for(const fValues in cost){
answer.push({"ref":`info${counter}.df${counter}.cost${i+1}.${fValues}`, "val": cost[fValues]})
}
} else{
answer.push({"ref":`info${counter}.df${counter}.cost${i+1}`,"val":cost})
}
}
}
console.log(answer)
输出:
[
{ ref: 'no', value: null },
{ ref: 'uid', value: null },
{ ref: 'details', value: 'detail' },
{ ref: 'phone', value: 'contact' },
{ ref: 'dataBody.area', value: 'Universe' },
{ ref: 'dataBody.place', value: 'LMN' },
{ ref: 'dataBody.information1', value: [ [Object] ] },
{ ref: 'dataBody.petName', value: 'Tiger' },
{ ref: 'hobby.indoor', value: false },
{ ref: 'hobby.outdoor', value: true },
{ ref: 'info1.code', value: 'abc' },
{ ref: 'info1.group', value: 'xyz' },
{ ref: 'info1.df1.definition1.type', val: 'up' },
{ ref: 'info1.df1.definition1.features.featurekey', val: 'ABC' },
{ ref: 'info1.df1.definition1.features.featureValues', val: null },
{ ref: 'info1.df1.definition1.mandatory', val: true },
{ ref: 'info1.df1.cost1.currency', val: 'USD' },
{ ref: 'info1.df1.cost1.value', val: 1 },
{ ref: 'info1.df1.definition2.type', val: 'down' },
{ ref: 'info1.df1.definition2.mandatory', val: true },
{ ref: 'info1.df1.cost2', val: '100' },
{ ref: 'info1.df1.definition3.type', val: 'left' },
{ ref: 'info1.df1.definition3.value', val: null },
{ ref: 'info1.df1.definition3.mandatory', val: true },
{ ref: 'info1.df1.cost3', val: false }
]
【问题讨论】:
标签: javascript arrays json typescript