如何深度删除对象中的键?

How to deeply remove keys in object?

我有一个从 API 返回的 json 对象,它有一些怪癖,我想对其进行规范化,以便我可以对每个响应处理相同的输入。这些意味着摆脱多余的键:

回复:

{
  _links: {...},
  _embedded: {
    foo: [
      {
        id: 2,
        _embedded: {
          bar: []
        }
      }
    ]
  }
}

所以我想删除所有 _embedded 键并将其展平,如下所示:

{
  _links: {...},
  foo: [
    {
      id: 2,
      bar: []
    }
  ]
}

这就是我目前所拥有的,但它只适用于顶层,我认为它不能很好地与数组一起使用。

_.reduce(temp1, function(accumulator, value, key) {
  if (key === '_embedded') {
    return _.merge(accumulator, value);
  }
  return accumulator[key] = value;
}, {})

一旦你看到一个以 _ 开头的键,就递归循环你的所有键 简单地删除它。

Code:

var
// The keys we want to remove from the Object
        KEYS_TO_REMOVE = ['_embedded'],

// The data which we will use
        data = {
            _links: {'a': 1},
            _embedded: {
                foo: [
                    {
                        id: 2,
                        _embedded: {
                            bar: []
                        }
                    },
                    {
                        id: 3,
                        _embedded: {
                            bar: [
                                {
                                    id: 4,
                                    _embedded: {
                                        bar: []
                                    }
                                }
                            ]
                        }
                    }
                ]
            }
        };

/**
 * Flatten the given object and remove the desired keys if needed
 * @param obj
 */
function flattenObject(obj, flattenObj) {

    var key;

    // Check to see if we have flatten obj or not
    flattenObj = flattenObj || {};

    // Loop over all the object keys and process them
    for (key in obj) {

        // Check that we are running on the object key
        if (obj.hasOwnProperty(key)) {

            // Check to see if the current key is in the "black" list or not
            if (KEYS_TO_REMOVE.indexOf(key) === -1) {

                // Process the inner object without this key
                flattenObj[key] = flattenObject(obj[key], flattenObj[key]);
            } else {
                flattenObject(obj[key], flattenObj);
            }

        }
    }

    return flattenObj;


}

console.log(flattenObject(data));

所以,基本上你已经拥有了几乎所有你需要的代码。我们所要做的就是将它包装在一个函数中,这样我们就可以使用递归了。你会看到我们只添加一个检查来查看它是否是一个对象,如果是,我们已经有一个知道如何展平该对象的函数,所以我们只需使用我们需要展平的键再次调用它.

function flatten(temp1) {  // Wrap in a function so we can use recursion
  return _.reduce(temp1, function(accumulator, value, key) {
    if (key === '_embedded') {
      return _.merge(accumulator, value);
    } else if (value !== null && typeof value === 'object') // Check if it's another object
      return _.merge(accumulator, flatten(value)) // Call our function again
    return accumulator[key] = value;
  }, {})
}

我稍后会测试它,但这应该是你需要的。

知道了!

function unEmbed(data) { 
  return _.reduce(data, function(accumulator, value, key) {
    const returnableValue = _.isObject(value) ? unEmbed(value) : value;
    if (key === 'embedded') {
      return _.merge(accumulator, returnableValue);
    }
    accumulator[key] = returnableValue;
    return accumulator;
  }, {});
}

我返回 return accumulator[key] = returnableValue 之前出现问题,结果是 return returnableValue