【问题标题】:Javascript delete nested object properties by name [duplicate]Javascript按名称删除嵌套对象属性[重复]
【发布时间】:2020-11-03 18:53:01
【问题描述】:

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

例如:

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

如何删除名称/键为“deleteMe”的每个字段。我提前不知道对象的结构。

【问题讨论】:

  • 递归是一个好的开始。
  • 查看之前的评论
  • 首先你要知道一个对象中有多少个对象

标签: javascript


【解决方案1】:

您需要在对象中找到键或递归下降到本身就是对象的任何值:

function deleteMe(obj, match) {
  delete obj[match];
  for (let v of Object.values(obj)) {
    if (v instanceof Object) {
      deleteMe(v, match);
    }
  }
}

【讨论】:

    【解决方案2】:

    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);

    【讨论】:

      【解决方案3】:

      您可以递归遍历每个嵌套对象并在每个级别删除您想要的任何键。

      请注意,这将修改现有对象。

      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 那是因为该函数允许您传入多个键。如果有的话,它可以更好地理解每一步发生的事情。任何人都可以对此进行改进。而且我也喜欢我被否决的工作算法。这不是Code Review...
      • @Alnitak 不管怎样,我将 forEach 更改为 for-in 循环,并将键包装在一个集合中以便更有效地查找。
      【解决方案4】:

      这样的事情应该可以工作:

      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

      【讨论】:

      • 不错,虽然在对象中不能重复键,因此不需要遍历每个键
      猜你喜欢
      • 2017-06-02
      • 1970-01-01
      • 2021-05-09
      • 1970-01-01
      • 2019-08-27
      • 1970-01-01
      • 1970-01-01
      • 2021-09-27
      • 2021-10-19
      相关资源
      最近更新 更多