【问题标题】:JavaScript - Built in Function to Delete Multiple Keys in an Object?JavaScript - 内置函数删除对象中的多个键?
【发布时间】:2015-09-12 02:34:57
【问题描述】:

在 JavaScript 中,我可以删除对象的键

delete myObject[myKey];

有时,我需要删除相当多的键,但不是父键中包含我要删除的键的所有值。

有没有一种使用一行删除多个键的有效方法?看起来像:

multiDelete myObject[keyOne, keyTwo, keyThree];

【问题讨论】:

  • 从什么角度看高效?首先使用delete 效率已经很低了。
  • 但不是父键中包含我要删除的键的所有值你能澄清一下吗? “父键”或“封装键”是什么意思?

标签: javascript


【解决方案1】:

这是一个与您要求的类似的单行。

var obj = {a: 1, b: 2, c: 3, d: 4, e: 5 };

['c', 'e'].forEach(e => delete obj[e]);

// obj is now {a:1, b:2, d:4}

【讨论】:

    【解决方案2】:

    您也可以使用对象解构。

    const obj = {
            a: 'dog',
            b: 'cat',
            c: 'mouse',
            d: 'cow',
            e: 'horse',
        };
    const {a, e, ...updatedObject} = obj;
    
    // output
    console.log(updatedObject)

    【讨论】:

    • 请注意,使用此方法您还声明了变量 a 和 e,它们分别等于 'dog' 和 'horse'。
    • 这是首选,因为它不会改变原始对象
    • 问题要求删除具有 DYNAMIC 字段名称的键,而此答案未能解决问题的该元素。
    【解决方案3】:

    目前还没有内置的 js 函数来删除多个键,您可以使用任何库来执行此操作,例如 underscore.js

    _.omit({name: 'moe', age: 50, userid: 'moe1'}, 'userid');
    => {name: 'moe', age: 50}
    
    //or you can use function to filter keys 
    
    _.omit({name: 'moe', age: 50, userid: 'moe1'}, function(value, key, object){
      return _.isNumber(value);
    });
    => {name: 'moe', userid: 'moe1'}
    

    【讨论】:

      【解决方案4】:

      使用库 lodash 有一个简单的修复方法。

      _.omit 函数获取您的对象和要删除的键数组,并返回一个新对象,该对象具有原始对象的所有属性,但数组中提到的属性除外。

      这是一种删除键的巧妙方法,因为使用它可以获得一个新对象,而原始对象保持不变。这避免了突变问题,如果我们删除原始对象中的键,则使用该对象的所有其他代码部分可能会破坏或在代码中引入错误。

      例子:

      var obj = {x:1, y:2, z:3};
      var result = _.omit(obj, ['x','y']);
      console.log(result);
      
      //Output
      result = {z:3};
      

      同一文档的链接点击Here

      【讨论】:

        【解决方案5】:

        没有内置函数,但一种方法是将multidelete 方法添加到对象原型。这可能有点矫枉过正,但您可能会发现它很有用。

        if (!('multidelete' in Object.prototype)) {
            Object.defineProperty(Object.prototype, 'multidelete', {
                value: function () {
                    for (var i = 0; i < arguments.length; i++) {
                        delete this[arguments[i]];
                    }
                }
            });
        }
        
        var obj = { a: 1, b: 2, c: 3, d: 4, e: 5 };
        
        obj.multidelete('c', 'e'); // { a: 1, b: 2, d: 4 };
        

        DEMO

        【讨论】:

        • 如果您要像这样循环参数,则无需先对其进行切片。另外,enumerableconfigurable 默认为false,不需要显式指定。
        【解决方案6】:

        您可以创建一个键数组以通过字符串删除并遍历对象以删除它们

        var obj = {key1: 1, key2: 2, key3: 3 };
        
        "key1 key2 key3".split(" ").forEach(e => delete obj[e]);
        

        【讨论】:

          【解决方案7】:

          如果您想要一个内置的解决方案,您可以添加一个类似于Object.defineProperties() 的实用程序函数,这样您就可以向给定对象添加属性,但现在也可以通过提交null 属性来删除属性描述符。

          如果属性描述符不是对象,Object.defineProperties() 会抛出错误,因此我们可以安全地使用“假”值来指示要删除该属性。

          代码如下:

          function unDefineProperties(obj, propertyDescriptors) {
            const [normalDescriptors, toBeDeletedDescriptors] =
              partition(Object.entries(propertyDescriptors),([_, descriptor]) => descriptor);
            Object.defineProperties(obj, Object.fromEntries(normalDescriptors));
            toBeDeletedDescriptors.forEach(([name, _]) => delete obj[name]);
            return obj;
          }
          

          函数名应该读作“(un)define properties”,即“define or delete properties”。

          它使用实用函数partition(定义在下面的代码 sn-p 中,借用自 this answer)。

          然后它调用Object.defineProperties(),并使用从“正常”条目重构的属性描述符对象。

          之后(因为第一步可能由于不正确的属性描述符而失败),所有“待删除”条目删除obj中的相应属性。

          最后,obj 被返回,以模仿 Object.defineProperties() 的便捷行为。

          生成的函数与原始 Object.defineProperties() 兼容(当然除了“虚假”属性描述符的行为),因此可以用作原始函数的替代品。如果您想这样做,为了保持一致性,您还应该将Object.defineProperty()(单数!)替换为类似的函数,该函数通过删除相应的属性来处理“虚假”属性描述符(留给读者作为练习;-)) .

          下面是完整的代码和用法示例:

          function partition(array, filter) {
            let pass = [], fail = [];
            array.forEach((e, idx, arr) => (filter(e, idx, arr) ? pass : fail).push(e));
            return [pass, fail];
          }
          
          function unDefineProperties(obj, propertyDescriptors) {
            const [normalDescriptors, toBeDeletedDescriptors] =
              partition(Object.entries(propertyDescriptors),([_, descriptor]) => descriptor);
            Object.defineProperties(obj, Object.fromEntries(normalDescriptors));
            toBeDeletedDescriptors.forEach(([name, _]) => delete obj[name]);
            return obj;
          }
          
          // Usage example:
          
          const obj = { a: 'A', b: 'B', c: 'C'};
          
          unDefineProperties(obj, {
            a: null,
            c: null,
            d: { value: "D", enumerable: true }
          });
          
          console.log(obj); // logs { "b": "B", "d": "D" }

          【讨论】:

            【解决方案8】:

            10 ways to delete property from an object

            
            
            const obj = {
                'first': 'one',
                'second': 'two',
                'third': 'three'
            }
            
            let filtered = {}
            for (const key in obj) {
                if (key !== 'second') {
                    filtered[key] = obj[key]
                }
            }
            
            console.log(filtered)        //  { 'first': 'one', 'third': 'three' }
            

            【讨论】:

              猜你喜欢
              • 2020-10-30
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-11-20
              • 1970-01-01
              • 2018-04-20
              • 2018-07-28
              相关资源
              最近更新 更多