Javascript 递归规范化 JSON 数据 [英] Javascript Recursion normalize JSON data

查看:49
本文介绍了Javascript 递归规范化 JSON 数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个json响应,我想通过递归和reduce来简化这个json数据.我写了一个函数把我卡在了这一点上.我想删除所有数据元素并创建一个没有数据名称的新对象.

我的json数据是这样的

<预><代码>[{城市": {数据": {身份证":649442,"country_id": 54,state_id":682,"city_name": "布拉格","state_name": "布拉格"}},国家": {数据": {身份证":54,数据": {"country_name": "捷克共和国","short_country": "CZ","olympic_code": "捷克"}}}}]

我的函数在这里:

function normalizeData(object) {返回 Object.keys(object).reduce((finalObject, objectKey) => {if (object[objectKey] && object[objectKey].data) {finalObject[objectKey] = object[objectKey].data;如果(Array.isArray(finalObject[objectKey].data)){finalObject[objectKey] = object[objectKey].data.map(item => {返回 normalizeData(item);});} 别的 {finalObject[objectKey] = normalizeData(object[objectKey].data);}} 别的 {finalObject[objectKey] = object[objectKey];}返回最终对象;}, {});};

我仍然在获取数据对象.那么我在哪里出错了.或者有没有更好的方法来做到这一点?

解决方案

这是一个没有 reduce() 的解决方案,它检查对象属性是否没有被继承 (hasOwnProperty()),并对作为对象本身的每个属性进行递归.它的属性键是 data,然后所有的值都被复制到父对象,然后 data 键会从对象中删除.这就是它变得棘手的地方,因为 data 对象本身可以具有 data 属性,因此必须对其进行检查并需要应用双重递归.

var jsonStr = `{城市": {数据": {身份证":649442,"country_id": 54,state_id":682,"city_name": "布拉格","state_name": "布拉格"}},国家": {数据": {身份证":54,数据": {"country_name": "捷克共和国","short_country": "CZ","olympic_code": "捷克"}}}}`;var jo = JSON.parse(jsonStr);函数归一化(obj){for(obj中的var键){如果(obj.hasOwnProperty(键)){if (typeof obj[key] === 'object') {如果(键 === '数据'){//检查数据对象是否也有数据属性if (obj[key].hasOwnProperty('data')) {//双递归规范化(对象 [key]);归一化(对象);}别的 {//将所有值复制到父级//(仅当它们不存在于父级中时)for (var subKey in obj[key]) {if (obj[key].hasOwnProperty(subKey)&&!obj.hasOwnProperty(subKey)) {obj[subKey] = obj[key][subKey];}}//删除数据键删除 obj[key];}}别的 {//递归规范化(对象 [key]);}}}}}标准化(乔);console.log(jo);

您可以使用 deep extend 首先创建对象的副本并返回该副本,如果您不希望函数修改输入.

I have a json response and I want to simplify this json data with recursion and reduce. I write a function put i stuck at this point. I want to remove all data element and create a new object without data name.

My json data is like this

[
    {
        "city": {
            "data": {
                "id": 649442,
                "country_id": 54,
                "state_id": 682,
                "city_name": "Prague",
                "state_name": "Praha"
            }
        },
        "country": {
            "data": {
                "id": 54,
                "data": {
                    "country_name": "Czech Republic",
                    "short_country": "CZ",
                    "olympic_code": "CZE"
                }
            }
        }
    }
]

And my function is here:

function normalizeData(object) {
  return Object.keys(object).reduce((finalObject, objectKey) => {
    if (object[objectKey] && object[objectKey].data) {
      finalObject[objectKey] = object[objectKey].data;
      if (Array.isArray(finalObject[objectKey].data)) {
        finalObject[objectKey] = object[objectKey].data.map(item => {
          return normalizeData(item);
        });
      } else {
        finalObject[objectKey] = normalizeData(object[objectKey].data);
      }
    } else {
      finalObject[objectKey] = object[objectKey];
    }
    return finalObject;
  }, {});
};

At the and I am still getting data object. So where am I making mistake. Or is there a better way to do this?

解决方案

This is a solution without reduce(), that checks if the object properties are not inherited (hasOwnProperty()), and does a recursion for each property that is an object itself. It the property key is data, then all the values get copied to the parent object and the data key gets deleted from the object afterwards. This is where it gets tricky because the data object can have a data property itself, so this has to be checked and a double recursion needs to be applied.

var jsonStr = `{
    "city": {
        "data": {
            "id": 649442,
            "country_id": 54,
            "state_id": 682,
            "city_name": "Prague",
            "state_name": "Praha"
        }
    },
    "country": {
        "data": {
            "id": 54,
            "data": {
                "country_name": "Czech Republic",
                "short_country": "CZ",
                "olympic_code": "CZE"
            }
        }
    }
}`;

var jo = JSON.parse(jsonStr);

function normalize(obj) {
    for (var key in obj) {
        if (obj.hasOwnProperty(key)) {
            if (typeof obj[key] === 'object') {
                if (key === 'data') {
                    // check if data object also has a data property
                    if (obj[key].hasOwnProperty('data')) {
                        // double recursion
                        normalize(obj[key]);
                        normalize(obj);
                    }
                    else {
                        // copy all values to the parent
                        // (only if they don't exist in the parent yet)
                        for (var subKey in obj[key]) {
                            if (obj[key].hasOwnProperty(subKey)
                            &&  !obj.hasOwnProperty(subKey)) {
                                obj[subKey] = obj[key][subKey];
                            }
                        }
                        // remove the data key
                        delete obj[key];
                    }
                }
                else {
                    // recursion
                    normalize(obj[key]);
                }
            }
        }
    }
}

normalize(jo);

console.log(jo);

you can use a deep extend to create a copy of the object first and return that one, if you don't want the function to modify the input.

这篇关于Javascript 递归规范化 JSON 数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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