如何从任何级别的嵌套javascript对象中删除属性

How to remove a property from nested javascript objects any level deep?

本文关键字:对象 javascript 删除 属性 嵌套 任何级      更新时间:2023-09-26

假设我有嵌套的对象,比如:

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

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

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

没有直接的方法可以实现这一点,但是您可以使用下面的函数从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 obj[key];
        }
    }
    return obj;
}

并像一样使用它

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

修改上述解决方案,删除"dataID";它在我的JSON中多次出现。下面提到的代码运行良好。

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
}

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

我们现在使用对象扫描来执行这样的数据处理任务。一旦你把你的头缠在它周围,它就会非常强大。以下是你如何回答你的问题

// 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>

免责声明:我是对象扫描的作者

我也遇到过类似的问题。因此,我开发了以下库。请在GitHub上查看该库的源代码,您可以使用npm下载它。

您可以将函数removePropertiesDeeplyisInitialized一起使用,如下所示,以删除所有未初始化的属性(如空对象、空数组、空字符串或非有限数)。

const {removePropertiesDeeply, isInitialized} = require("@thedolphinos/utility4js");
const object = {
  a: null,
  b: "",
  x: {
    a: null,
    b: ""
  },
  y: [],
  z: [
    null,
    "",
    {a: null, b: ""},
    [[{a: {b: null, c: ""}}]],
    "abc"
  ]
};
removePropertiesDeeply(object, (x) => !isInitialized(x));
console.log(JSON.stringify(object)); // See that the object becomes {"z":["abc"]}.

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

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

const newObject = {
   ...obj.items,
   ...obj.name,
   options: null // option property will be null.
}
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;
}

您可以使用以下函数删除给定条件的属性:

// Warning: this function mutates original object
const removeProperties = (obj, condition = (key, value) => false) => {
  for (var key in obj) {
    const value = obj[key]
    if (!obj.hasOwnProperty(key)) continue
    if (typeof obj[key] === "object") {
      removeProperties(obj[key], condition)
    } else if (condition(key, value)) {
      delete obj[key]
    }
  }
  return obj
}

示例:

// Remove all properties where key is equal to 'options'
removeProperties(someObject, (key, value) => key === 'options'))

// Remove all properties where key starts with 'ignore_'
removeProperties(someObject, (key, value) => key.startsWith('ignore_'))

// Remove all properties where value is null
removeProperties(someObject, (key, value) => value === null))