首页 > 解决方案 > 用 JS 递归转换我的 JSON 数据

问题描述

我试图弄清楚如何转换我从 Web 服务返回的一些 JSON,以便我可以轻松地将其解析为一个很好的类型安全对象。我想将此格式转换为:

[{
        "name": "AwesomePeople",
        "value": [
            [{
                    "name": "TypeId",
                    "value": 1
                }, {
                    "name": "People",
                    "value": [

                        [{
                                "name": "id",
                                "value": 2
                            }, {
                                "name": "name",
                                "value": "Danno"
                            }
                        ],
                        [{
                                "name": "id",
                                "value": 3
                            }, {
                                "name": "name",
                                "value": "Julio"
                            }
                        ]
                    ]
                }
            ],
            [{
                    "name": "TypeId",
                    "value": 2
                }, {
                    "name": "People",
                    "value": [
                        [{
                                "name": "id",
                                "value": 4
                            }, {
                                "name": "name",
                                "value": "Jenna"
                            }
                        ],
                        [{
                                "name": "id",
                                "value": 5
                            }, {
                                "name": "name",
                                "value": "Coolio"
                            }
                        ]
                    ]
                }
            ]
        ]
    }
]

转为以下格式:

[{
        "AwesomePeople": [
            [{
                    "TypeId": 1,
                }, {
                    "People": [

                        [{
                                "id": 2
                            }, {
                                "firstName":"Danno"
                            }
                        ],
                        [{
                                "id": 3,
                            }, {
                                "firstName": "Julio"
                            }
                        ]
                    ]
                }
            ],
            [{
                    "TypeId": 2
                }, {
                    "People": [
                        [{
                                "id": 4
                            }, {
                                "firstName": "Jenna"
                            }
                        ],
                        [{
                                "id": 5
                            }, {
                                "firstName": "Coolio"
                            }
                        ]
                    ]
                }
            ]
        ]
    }
];

需要发生两件主要的事情,这些愚蠢的“名称”/“值”对需要在任何和所有级别进行交换。例如,不是“name”:“id”、“value”:“3”,而是“id”:3。这些值有时是数组,所以它们需要以类似的方式处理......深度是可变的,所以我不能假设一定数量的深度,所以我需要继续递归处理所有内容。

我已经开始使用下面的代码......你会看到一个空的“newResult”数组,当我遍历原始 JSON 时,我正在尝试构建它,无论我当前正在查看一个对象还是一个数组,都会采取不同的操作,或密钥/属性。

let count = 0;
let result = <the original array above>
let newResult = [];
 result.forEach(function(resObj) {
   console.log("STARTING to TRAVERSE HIGHER LEVEL OBJECTS!");
    traverse(resObj);
   count++;
   
   //we're done processing high level objects, so return from this function and enjoy the newResult!
   if (count===result.length) 
     //return from this function
     console.log(newResult);
       console.log("FINISHED PROCESSING HIGHER LEVEL OBJECTS, SO DONE!");
   
  });


//Below are the functions for traversing 
function traverse(x, level) {
  if (isArray(x)) {
    console.log("array");
    traverseArray(x);
  } else if ((typeof x === 'object') && (x !== null)) {
    console.log("object");
    traverseObject(x);
  } else {
     console.log("property: "+x);
     //console.log(level + x);
  }
}

function isArray(o) {
  return Object.prototype.toString.call(o) === '[object Array]';
}

function traverseArray(arr, level) {
  //console.log(level + "<array>");
  arr.forEach(function(x) {
    traverse(x);
  });
}

function traverseObject(obj, level) {
  var keyName, keyValue;
  //console.log(level + "<object>");
  for (var key in obj) {
    if (obj.hasOwnProperty(key)) {
      if (key==="name"){
        keyName = obj[key];
        
      }else if (key==="value"){
        keyValue = obj[key];
      }
      if (keyName && keyValue){
        var newObj = {[keyName]: keyValue}
        newResult.push(newObj);
        //console.log("the KEY NAME IS: "+ keyName + ", and the VALUE is: "+keyValue);
      }
      //if we have a key value, but the value is an array, stop and 
     // if (isArray(newOj)
      console.log("traversing..." +obj[key]);
      
      traverse(obj[key]);
    }//end if property
  }//end foreach key in object
  
}//end traverseObject

谢谢大家......感谢那些可以解决这个问题的人:)

标签: javascriptjsonrecursiontreetransform

解决方案


您可以使用JSON.stringifyand JSON.parse- 使用 reviver 执行此操作,检查该值是否具有name属性,如果有,则返回{ [value.name]: value.value }

const arr=[{name:"AwesomePeople",value:[[{name:"TypeId",value:1},{name:"People",value:[[{name:"id",value:2},{name:"name",value:"Danno"}],[{name:"id",value:3},{name:"name",value:"Julio"}]]}],[{name:"TypeId",value:2},{name:"People",value:[[{name:"id",value:4},{name:"name",value:"Jenna"}],[{name:"id",value:5},{name:"name",value:"Coolio"}]]}]]}];

const result = JSON.parse(JSON.stringify(arr, (key, value) => (
  value?.name
    ? { [value.name]: value.value }
    : value
)));
console.log(result);

如果您还想将name值更改为firstName键,请在计算属性中添加条件:

const arr=[{name:"AwesomePeople",value:[[{name:"TypeId",value:1},{name:"People",value:[[{name:"id",value:2},{name:"name",value:"Danno"}],[{name:"id",value:3},{name:"name",value:"Julio"}]]}],[{name:"TypeId",value:2},{name:"People",value:[[{name:"id",value:4},{name:"name",value:"Jenna"}],[{name:"id",value:5},{name:"name",value:"Coolio"}]]}]]}];

const result = JSON.parse(JSON.stringify(arr, (key, value) => (
  value?.name
    ? { [value.name === 'name' ? 'firstName' : value.name]: value.value }
    : value
)));
console.log(result);

手动:

const arr=[{name:"AwesomePeople",value:[[{name:"TypeId",value:1},{name:"People",value:[[{name:"id",value:2},{name:"name",value:"Danno"}],[{name:"id",value:3},{name:"name",value:"Julio"}]]}],[{name:"TypeId",value:2},{name:"People",value:[[{name:"id",value:4},{name:"name",value:"Jenna"}],[{name:"id",value:5},{name:"name",value:"Coolio"}]]}]]}];

const recurse = (val) => {
  if (!val || typeof val !== 'object') return val;
  if (Array.isArray(val)) return val.map(recurse);
  return { [val.name === 'name' ? 'firstName' : val.name]: val.value };
};


const result = recurse(arr);
console.log(result);


推荐阅读