Javascript递归规范化JSON数据

时间:2016-09-30 10:02:07

标签: javascript json recursion reduce

我有一个json响应,我希望通过递归和reduce来简化这个json数据。我写了一个功能,让我陷入困境。我想删除所有数据元素并创建一个没有数据名称的新对象。

我的json数据就像这样

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

我的功能在这里:

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;
  }, {});
};

在和我仍然得到数据对象。所以我在哪里弄错了。或者有更好的方法吗?

2 个答案:

答案 0 :(得分:0)

这是一个没有reduce()的解决方案,用于检查对象属性是否未被继承(hasOwnProperty()),并对作为对象本身的每个属性进行递归。属性键为data,然后将所有值复制到父对象,然后从对象中删除data键。这是棘手的,因为data对象本身可以有data属性,因此必须检查并且需要应用双递归。

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);

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

答案 1 :(得分:0)

我发现了自己的错误。我在对象上面有一个数组:)所以我修改了这样的代码。

export 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;
  }, {});
}

export function normalizeArray(array) {
  return array.map(object => {
    return normalizeData(object);
  })
}