Javascript 递归归一化 JSON 数据

Javascript Recursion normalize JSON data

我有一个 json 响应,我想通过递归和减少来简化这个 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;
  }, {});
};

我仍在获取数据对象。那么我在哪里犯错了。或者有更好的方法吗?

这是一个没有 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 创建对象的副本,然后 return 如果您不希望函数修改输入,则

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

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