从嵌套的 javascript 对象中删除属性的最佳方法是啥?

Posted

技术标签:

【中文标题】从嵌套的 javascript 对象中删除属性的最佳方法是啥?【英文标题】:Whats the best way to remove a property from nested javascript Object?从嵌套的 javascript 对象中删除属性的最佳方法是什么? 【发布时间】:2012-12-29 22:37:03 【问题描述】:

我有一个如下的树对象,如果它是空的,我正在尝试删除 items 数组属性。我不确定执行此操作的最佳方法?

我正在考虑循环访问密钥,检查属性,然后使用 delete myJSONObject[prop] 删除...欢迎任何想法/想法?

[
    text: "TreeRoot",
    items: [
        text: "Subgroup1",
        items: []
    , 
        text: "Subgroup2",
        items: []
    , 
        text: "Subgroup3",
        items: [],
        items: [
            text: "subgroup5",
            items: [
                text: "subgroup6",
                items: [
                    text: "subgroup7",
                    items: [
                        text: "subgroup8",
                        items: []
                    ]
                ]
            ]
        ]
    ]
]

【问题讨论】:

我会构建一个新对象,而不是尝试修改这个。 嘿,你解决了吗? ***.com/questions/9446426/… 【参考方案1】:

您可以使用递归算法,在每一步删除 items 数组并返回,或递归处理数组的每个单独对象。

我也会尝试在服务器端执行此操作。它将节省大量复杂性、内存和处理时间。通常有一些方法可以从 JSON 编码的字符串中“排除”空数组。

【讨论】:

【参考方案2】:

这应该可以完成工作(ES5):

function removeEmpty(obj) 
  Object.keys(obj).forEach(function(key) 
    (key === 'items' && obj[key].length === 0) && delete obj[key] ||
    (obj[key] && typeof obj[key] === 'object') && removeEmpty(obj[key])
  );
  return obj;
;

JSBIN

ES6 中相同:

const removeEmpty = (obj) => 
  Object.keys(obj).forEach(key =>
    (key === 'items' && obj[key].length === 0) && delete obj[key] ||
    (obj[key] && typeof obj[key] === 'object') && removeEmpty(obj[key])
  );
  return obj;
;

JSBIN

【讨论】:

【参考方案3】:

这是使用object-scan的解决方案

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

const data = [ text: 'TreeRoot', items: [ text: 'Subgroup1', items: [] ,  text: 'Subgroup2', items: [] ,  text: 'Subgroup3', items: [ text: 'subgroup5', items: [ text: 'subgroup6', items: [ text: 'subgroup7', items: [ text: 'subgroup8', items: [] ] ] ] ] ] ];

const modify = (obj) => objectScan(['**.items'], 
  rtn: 'count',
  filterFn: ( value, parent, property ) => 
    if (Array.isArray(value) && value.length === 0) 
      delete parent[property];
      return true;
    
    return false;
  
)(obj);

console.log(modify(data)); // returns number of deletions
// => 3
console.log(data);
// => [  text: 'TreeRoot', items: [  text: 'Subgroup1' ,  text: 'Subgroup2' ,  text: 'Subgroup3', items: [  text: 'subgroup5', items: [  text: 'subgroup6', items: [  text: 'subgroup7', items: [  text: 'subgroup8'  ]  ]  ]  ]  ]  ]
.as-console-wrapper max-height: 100% !important; top: 0
<script src="https://bundle.run/object-scan@13.7.1"></script>

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

【讨论】:

【参考方案4】:

这个老问题已经被提出来了,我认为现代 JS 与递归配合得很好,可以产生一个简单的答案,以不可变的方式做到这一点:

const removeEmptyItems = (xs) =>
   xs .map ((items = [], ... rest) => (
    ... rest, 
    ... (items .length ? items: removeEmptyItems(items) : )
  ))

const tree = [text: "TreeRoot", items: [text: "Subgroup1", items: [], text: "Subgroup2", items: [], text: "Subgroup3",items: [text: "subgroup5", items: [text: "subgroup6", items: [text: "subgroup7", items: [text: "subgroup8", items: []]]]]]]

console .log (removeEmptyItems (tree))
.as-console-wrapper max-height: 100% !important; top: 0

这个函数只是简单地映射数组,保留每个对象的其余部分,并为其items 属性,当它为空时跳过它,当它不是空时重复。

我不得不说,当第一次问这个问题时,这个答案看起来很陌生!现在它只是普通的JS!

【讨论】:

以上是关于从嵌套的 javascript 对象中删除属性的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

javascript 从dynamoDB中删除嵌套属性

从嵌套地图对象javascript中删除重复项

从数组中的嵌套对象中删除对象属性

当从扩展符号访问对象时如何访问 Javascript 对象的嵌套按名称属性...?

从对象中删除属性 (JavaScript)

从对象中删除属性 (JavaScript)