【问题标题】:How to remove a property from nested javascript objects any level deep?如何从任何级别的嵌套javascript对象中删除属性?
【发布时间】:2016-04-09 01:01:23
【问题描述】:

假设我有嵌套对象,例如:

var obj = {
    "items":[
        {
            "name":"Item 1", 
            "value": "500",
            "options": [{...},{...}]
        },
        {
            "name":"Item 2", 
            "value": "300",
            "options": [{...},{...}]
        }
    ],
    "name": "Category",
    "options": [{...},{...}]
};

我想从所有对象的任何深处删除 options 属性。对象可以嵌套在对象中,数组也可以。

我们目前在项目中使用 Lodash,但我对任何解决方案感到好奇。

【问题讨论】:

标签: javascript object lodash


【解决方案1】:

没有直接的方法可以实现这一点,但是您可以使用下面的函数从 JSON 中删除密钥。

function filterObject(obj, key) {
    for (var i in obj) {
        if (!obj.hasOwnProperty(i)) continue;
        if (typeof obj[i] == 'object') {
            filterObject(obj[i], key);
        } else if (i == key) {
            delete key;
        }
    }
    return obj;
}

并像使用它

var newObject = filterObject(old_json, "option");

【讨论】:

  • 嗯,我们的代码库处于严格模式,我收到以下错误:Uncaught SyntaxError: Delete of an unqualified identifier in strict mode。
  • @void 有没有一种方法可以在没有递归的情况下做到这一点,即使使用此处发布的类似解决方案softwareengineering.stackexchange.com/a/323670,我也会不断收到“RangeError:超出最大调用堆栈大小”
  • @erotavlas 也许您只需要传递对象的一部分而不是完整的对象。这将减少迭代次数。
  • 好像是删除键;应该是 delete obj[key];
  • 如果键包含对象作为值,那么@sboyd 解决方案here 的结构更好。
【解决方案2】:

修改上述解决方案,删除在我的 JSON 中多次出现的“dataID”。下面提到的代码工作正常。

var candidate = {
  "__dataID__": "Y2FuZGlkYXRlOjkuOTI3NDE5MDExMDU0Mjc2",
  "identity": {
    "__dataID__": "aWRlbnRpdHk6NjRmcDR2cnhneGE3NGNoZA==",
    "name": "Sumanth Suvarnas"
  },  
};

candidate = removeProp(candidate, "__dataID__")

console.log(JSON.stringify(candidate, undefined, 2));

function removeProp(obj, propToDelete) {
   for (var property in obj) {
      if (typeof obj[property] == "object") {
         delete obj.property
         let newJsonData= this.removeProp(obj[property], propToDelete);
         obj[property]= newJsonData
      } else {
          if (property === propToDelete) {
            delete obj[property];
          }
        }
    }
    return obj
}

【讨论】:

  • delete obj.property 是错字吗?
【解决方案3】:

我们现在使用object-scan 来完成这样的数据处理任务。一旦你把头绕在它周围,它就非常强大。以下是您回答问题的方式

// const objectScan = require('object-scan');

const prune = (input) => objectScan(['**.options'], {
  rtn: 'count',
  filterFn: ({ parent, property }) => {
    delete parent[property];
  }
})(input);

const obj = { items: [{ name: 'Item 1', value: '500', options: [{}, {}] }, { name: 'Item 2', value: '300', options: [{}, {}] }], name: 'Category', options: [{}, {}] };

console.log(prune(obj));
// => 3

console.log(obj);
// => { items: [ { name: 'Item 1', value: '500' }, { name: 'Item 2', value: '300' } ], name: 'Category' }
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/object-scan@13.8.0"></script>

免责声明:我是object-scan的作者

【讨论】:

    【解决方案4】:

    对 void 的回答稍作修改,允许删除也是对象的属性

    function filterObject(obj, key) {
        for (var i in obj) {
            if (!obj.hasOwnProperty(i)) continue;
            if (i == key) {
                delete obj[key];
            } else if (typeof obj[i] == 'object') {
                filterObject(obj[i], key);
            }
        }
        return obj;
    }
    

    【讨论】:

      【解决方案5】:

      我遇到了类似的问题,我已经解决了。我希望我的解决方案可能对某人有所帮助。

      我使用 Es6 ... 扩展运算符对对象进行浅拷贝,并将我不感兴趣的属性设为 null。

      const newObject = {
         ...obj.items,
         ...obj.name,
         options: null // option property will be null.
      }
      

      【讨论】:

      • undefined 会更准确,因为您正在删除信息
      【解决方案6】:
      function omit(source) {
        return isArray(source)
          ? source.map(omit)
          : isObject(source)
          ? (({ options, ...rst }) => mapValues(rst, omit))(source)
          : source;
      }
      

      和 lodash 一样,这很简单,你也可以像这样通过参数指定密钥

      function omit(source, omitKey) {
        return isArray(source)
          ? source.map(partialRight(omit,omitKey)))
          : isObject(source)
          ? (({[omitKey]: _, ...rst }) => mapValues(rst, partialRight(omit,omitKey)))(source)
          : source;
      }
      

      【讨论】:

        猜你喜欢
        • 2020-07-24
        • 2021-01-30
        • 2021-07-27
        • 2023-01-25
        • 2017-06-02
        • 2022-07-06
        • 1970-01-01
        • 2020-05-27
        相关资源
        最近更新 更多