使用 JS 递归转换我的 JSON 数据

Recursively Transform my JSON data with JS

我正在尝试弄清楚如何转换一些 JSON 我从 Web 服务返回的内容,以便我可以轻松地将它解析为一个不错的类型安全对象。我想从以下格式转换此格式:

[{
        "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,无论我是否采取不同的操作我目前正在查看对象、数组或 key/property.

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

感谢所有...感谢能够解决这个问题的人:)

您可以使用 JSON.stringifyJSON.parse 执行此操作 - 使用 reviver,检查该值是否具有 name 属性,如果有,return { [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);

我抓取了你的数据,快速编写了一个函数来转换它,来到 post 它并意识到我的输出根本不是你所要求的。我会把它扔掉,除了在我看来这个输出比你要求的有用得多。所以如果你可以使用这样的东西:

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

那么这个函数可能会有所帮助:

const convert = (xs) =>
  Object .fromEntries (
    xs .map (({name, value}) => [
      name, 
      Array .isArray (value) ? value .map (convert) : value
    ])
  )

const data = [{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"}]]}]]}]

console .log (convert (data))
.as-console-wrapper {min-height: 100% !important; top: 0}

如果没有,那么也许其他人可能会从中得到一些用处。

这是使用 object-scan 的答案。此代码修改原始输入,这比重建结构要快得多。

请注意,您输入的数据有点不一致:firstName 来自哪里?所以我假设一致性

// const objectScan = require('object-scan');

const data = [{ 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' } ] ] } ] ] } ];

objectScan(['**[*].name'], {
  filterFn: ({ parent }) => {
    const { name, value } = parent;
    delete parent.name;
    delete parent.value;
    parent[name] = value;
  }
})(data);

console.log(data);
// => [ { AwesomePeople: [ [ { TypeId: 1 }, { People: [ [ { id: 2 }, { name: 'Danno' } ], [ { id: 3 }, { name: 'Julio' } ] ] } ], [ { TypeId: 2 }, { People: [ [ { id: 4 }, { name: 'Jenna' } ], [ { id: 5 }, { name: 'Coolio' } ] ] } ] ] } ]
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/object-scan@14.0.0"></script>

免责声明:我是object-scan

的作者