Lodash递归删除项目

时间:2016-08-22 17:27:04

标签: javascript lodash

给定这个JSON对象,lodash如何从对象中删除reach值?

{ 
    total: 350,
    SN1: { 
        reach: 200,
        engagementRate: 1.35
    },
    SN2: {
        reach: 150,
        engagementRate: 1.19
    }
}

我一直在尝试迭代删除它()但我总是得到一个未定义的对象作为回报,所以我很肯定我做错了。 这也是我第一次使用lodash,这可能是实际问题。

有人可以帮忙吗?

6 个答案:

答案 0 :(得分:8)

_.transform()将对象传递给另一个对象,并在将值传递给新对象时,检查该值是否为对象,以及是否具有'到达'属性,如果是,请使用_.omit()获取没有reach的新对象:



var obj = {
  total: 350,
  SN1: {
    reach: 200,
    engagementRate: 1.35
  },
  SN2: {
    reach: 150,
    engagementRate: 1.19
  }
};

var result = _.transform(obj, function(result, value, key) {
  result[key] = _.isObject(value) && `reach` in value ? _.omit(value, 'reach') : value;
});

console.log(result);

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>
&#13;
&#13;
&#13;

如果你需要一个可以处理多个嵌套对象级别的递归解决方案,这里有deepOmit,它使用相同的想法,但没有_.omit,可以用来删除多个键(参见代码中的评论):

&#13;
&#13;
var obj = {
  total: 350,
  SN1: {
    reach: 200,
    engagementRate: 1.35,
    DEEP_SN1: {
      reach: 200,
      engagementRate: 1.35
    }
  },
  SN2: {
    reach: 150,
    engagementRate: 1.19
  }
};

function deepOmit(obj, keysToOmit) {
  var keysToOmitIndex =  _.keyBy(Array.isArray(keysToOmit) ? keysToOmit : [keysToOmit] ); // create an index object of the keys that should be omitted

  function omitFromObject(obj) { // the inner function which will be called recursivley
    return _.transform(obj, function(result, value, key) { // transform to a new object
      if (key in keysToOmitIndex) { // if the key is in the index skip it
        return;
      }

      result[key] = _.isObject(value) ? omitFromObject(value) : value; // if the key is an object run it through the inner function - omitFromObject
    })
  }
  
  return omitFromObject(obj); // return the inner function result
}

console.log(deepOmit(obj, 'reach')); // you can use a string for a single value

console.log(deepOmit(obj, ['reach', 'engagementRate'])); // you can use an array of strings for multiple values
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>
&#13;
&#13;
&#13;

答案 1 :(得分:3)

似乎没有深omit,但您可以迭代对象中的所有键,并以递归方式从嵌套对象中删除reach

function omitDeep(obj) {
  _.forIn(obj, function(value, key) {
    if (_.isObject(value)) {
      omitDeep(value);
    } else if (key === 'reach') {
      delete obj[key];
    }
  });
}

&#13;
&#13;
var obj = { 
  total: 350,
  SN1: { 
    reach: 200,
    engagementRate: 1.35
  },
  SN2: {
    reach: 150,
    engagementRate: 1.19
  }
};

function omitDeep(obj) {
  _.forIn(obj, function(value, key) {
    if (_.isObject(value)) {
      omitDeep(value);
    } else if (key === 'reach') {
      delete obj[key];
    }
  });
}
omitDeep(obj)
console.log(obj);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>
&#13;
&#13;
&#13;

答案 2 :(得分:1)

_.mapValues(object, v => _.isObject(v)? _.omit(v, 'reach'): v)
  

_.mapValues (object, [iteratee=_.identity])

     

使用与生成的对象和值相同的键创建对象   运行object到的每个自己的可枚举字符串键控属性   iteratee。使用三个参数调用iteratee:( value ,    key object )。

     

_.omit (object, [props])

     

创建一个由自己和继承的可枚举字符串组成的对象   未省略的object的键控属性。

答案 3 :(得分:1)

使用_.mixin扩展omitDeep方法:

_.mixin({
    'omitDeep': function(obj, predicate) {
        return _.transform(obj, function(result, value, key) {
            if (_.isObject(value)) {
                value = _.omitDeep(value, predicate);
            }
            var doOmit = predicate(value, key);
            if (!doOmit) {
                _.isArray(obj) ? result.push(value) : result[key] = value;
            }
        });
    }
});

var my = {
    "key1": {
        "key2": {
            "key3": [null, {
                "key4": "string",
                "key5": true,
                "key6": null,
                "key7": 8,
                "key7": undefined
            }, null]
        }
    }
};

console.log(my);
console.log("omit null:", _.omitDeep(my, _.isNull));
console.log("omit undefined:", _.omitDeep(my, _.isUndefined));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

答案 4 :(得分:0)

通过在ES6 + Typescript中定义排除键数组来递归地从对象中省略键。

omitDeep(myObject, [omitKey1, omitKey2, ...omitKeyN])

// omitDeep.ts

/**
 * Recursively remove keys from an object
 * @usage
 *
 * const input = {
 *   id: 1,
 *   __typename: '123',
 *   createdAt: '1020209',
 *   address: {
 *     id: 1,
 *     __typename: '123',
 *   },
 *   variants: [
 *     20,
 *     {
 *       id: 22,
 *       title: 'hello world',
 *       __typename: '123',
 *       createdAt: '1020209',
 *       variantOption: {
 *         id: 1,
 *         __typename: '123',
 *       },
 *     },
 *     {
 *       id: 32,
 *       __typename: '123',
 *       createdAt: '1020209',
 *     },
 *   ],
 * }
 *
 * const output = {
 *   id: 1,
 *   address: {
 *     id: 1,
 *   },
 *   variants: [
 *     20,
 *     {
 *       id: 22,
 *       title: 'hello world',
 *       variantOption: {
 *         id: 1,
 *       },
 *     },
 *     {
 *       id: 32,
 *     },
 *   ],
 * }
 *
 * expect(omitDeep(input, ['createdAt, 'updatedAt', __typename']).to.deep.equal(output) // true
 *
 * @param {object} input
 * @param {Array<number | string>>} excludes
 * @return {object}
 */
const omitDeep = (input: object, excludes: Array<number | string>): object => {
  return Object.entries(input).reduce((nextInput, [key, value]) => {
    const shouldExclude = excludes.includes(key)
    if (shouldExclude) return nextInput

    if (Array.isArray(value)) {
      const arrValue = value
      const nextValue = arrValue.map((arrItem) => {
        if (typeof arrItem === 'object') {
          return omitDeep(arrItem, excludes)
        }
        return arrItem
      })
      nextInput[key] = nextValue
      return nextInput
    } else if (typeof value === 'object') {
      nextInput[key] = omitDeep(value, excludes)
      return nextInput
    }

    nextInput[key] = value

    return nextInput
  }, {})
}

export default omitDeep

答案 5 :(得分:0)

我不得不从一个对象数组中递归地删除两个键的所有出现。 omit-deep-lodash库允许在一个衬里中递归地省略对象键和值。一个呼叫中可以删除多个键。 对于那些认为删除太不稳定的人来说,这是一个实用的解决方案。请确保在此处阅读注释。 omit-deep-lodash

const omitDeep = require("omit-deep-lodash");
 
omitDeep({a: "a", b: "b", c: {b: "b", d: {b: "b", f: "f"}}}, "b");
//=> {a: "a", c: {d: {f: "f"}}}
 
omitDeep({a: "a", b: "b", c: {b: "b", d: {b: "b", f: "f"}}}, "a", "b");