JavaScript通过名称删除嵌套对象属性

4

我有一个复杂的JavaScript对象,其中包含多个嵌套的数组和映射。我想删除该对象中所有给定名称的字段。

例如:

{
  "myObj":{
    "name":"John",
    "deleteMe":30,
    "cars":{
      "car1":"Ford",
      "car2":"BMW",
      "deleteMe":"Fiat",
      "wheels":{
        "one":"Round",
        "two":"Square",
        "deleteMe":"Fiat"
        }
    }
  }
}

我该如何删除所有名称/键为"deleteMe"的字段。我事先不知道对象的结构。

2
递归是一个不错的开始。 - Mr. Polywhirl
2
请查看先前的评论。 - Alnitak
首先,您必须知道对象中的对象数量。 - Engineer S. Saad
4个回答

4
你需要在对象中找到键,或递归地进入任何本身就是对象的值。
function deleteMe(obj, match) {
  delete obj[match];
  for (let v of Object.values(obj)) {
    if (v instanceof Object) {
      deleteMe(v, match);
    }
  }
}

3

const myObj =  {
  "name":"John",
  "deleteMe":30,
  "cars":{
    "car1":"Ford",
    "car2":"BMW",
    "deleteMe":"Fiat",
    "wheels":{
      "one":"Round",
      "two":"Square",
      "deleteMe":"Fiat"
      }
  }
}

const recursiveRemoveKey = (object, deleteKey) => {
  delete object[deleteKey];
  
  Object.values(object).forEach((val) => { 
    if (typeof val !== 'object') return;
    
    recursiveRemoveKey(val, deleteKey);
  })
}

recursiveRemoveKey(myObj, 'deleteMe');

console.log(myObj);


2
你可以递归遍历每个嵌套对象,并在每个级别上删除任何想要的键。
请注意,这将修改现有的对象。

const main = () => {
  console.log(pruneKeys(getData(), 'deleteMe'))
}

/** Wrapper */
const pruneKeys = (obj, ...keys) => {
  __pruneKeysInner(obj, new Set(keys.length && Array.isArray(keys[0])
    ? keys[0] : keys))
  return obj
}

/** Recursive call */
const __pruneKeysInner = (obj, keySet) => {
  if (obj != null && isObject(obj)) {
    for (key in obj) {
      if (keySet.has(key)) {
        delete obj[key]
      } else {
        __pruneKeysInner(obj[key], keySet)
      }
    }
  }
}

const isObject = n => Object.prototype.toString.call(n) === '[object Object]'

const getData = () => ({
  "myObj": {
    "name": "John",
    "deleteMe": 30,
    "cars": {
      "car1": "Ford",
      "car2": "BMW",
      "deleteMe": "Fiat",
      "wheels": {
        "one": "Round",
        "two": "Square",
        "deleteMe": "Fiat"
      }
    }
  }
})

main()
.as-console-wrapper {
  top: 0;
  max-height: 100% !important;
}


这太过复杂了,而且在 forEach 中使用 .includes 是非常低效的。 - Alnitak
太好了,非常感谢。我已经点赞了。 - F_SO_K
@Alnitak,这是因为该函数允许您传递多个键。如果有什么不同,它表明了对每个步骤发生的事情更好的理解。任何人都可以在此基础上进行改进。我也喜欢自己的工作算法被点踩的感觉。这不是代码审查... - Mr. Polywhirl
@Alnitak 无论如何,我将forEach改为了for-in循环,并且使用了set来封装键以进行更有效的查找。 - Mr. Polywhirl

0

Something like this should work :

const obj = {
  "myObj":{
    "name":"John",
    "deleteMe":30,
    "cars":{
      "car1":"Ford",
      "car2":"BMW",
      "deleteMe":"Fiat",
      "wheels":{
        "one":"Round",
        "two":"Square",
        "deleteMe":"Fiat"
        }
    }
  }
}


const deleteField = (obj, field) => {
  Object.keys(obj).forEach((key) => {
    if (key === field) {
      delete obj[key];
    } else if (typeof obj[key] === "object") {
      deleteField(obj[key], field);
    }
  })
}

deleteField(obj, "deleteMe");
console.log(obj);

https://jsbin.com/gejunokisa/edit?html,js,output


不错,虽然在对象中不能有重复的键,因此不需要遍历每个键。 - Abror Abdullaev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接