【问题标题】:remove object from nested array从嵌套数组中删除对象
【发布时间】:2016-03-25 21:40:39
【问题描述】:

我有一个像这样的家谱:

{

    "children": [{
        "name": "bob",
        "children": [{
            "name": "sam",
            "children": [{
                "name": "mike",
                "children": [{
                    "name": "elias",
                    "children": []
                }, {
                    "name": "rodriguez",
                    "children": []
                }]
            }]
        }]
    }]
}

"children" 是一个包含嵌套子数组的数组。 如何从这样的数组中删除对象? 假设我想删除名为“sam”的对象,这应该给我留下以下内容:

{
    "children": [{
        "name": "bob",
        "children": []
    }]
}

它的嵌套使我绊倒,我不知道如何开始。

感谢任何有关处理类似问题的教程的帮助或指导。

【问题讨论】:

  • 假设有很多sam,你想把它们都删除吗?
  • 根据他的问题的措辞,这是模棱两可的 - 但我会说你的解决方案假定了最好的解释。

标签: javascript arrays


【解决方案1】:

Recursion 是处理树木的好工具。

var tree = {

    "children": [{
        "name": "bob",
        "children": [{
            "name": "sam",
            "children": [{
                "name": "mike",
                "children": [{
                    "name": "elias",
                    "children": []
                }, {
                    "name": "rodriguez",
                    "children": []
                }]
            }]
        }]
    }]
}

function removeFromTree(parent, childNameToRemove){
  parent.children = parent.children
      .filter(function(child){ return child.name !== childNameToRemove})
      .map(function(child){ return removeFromTree(child, childNameToRemove)});
  return parent;
}
tree = removeFromTree(tree, 'elias')         
console.log(tree);
document.write(JSON.stringify(tree));

本教程看起来很有趣(“二叉树”和“图表”部分)。我认为这有助于实现您的要求:https://www.syncano.io/blog/data-structures-in-javascript/

【讨论】:

  • 应该将{"name":"rodriguez","children":[]} 从树中移除吗?
  • 啊,{"name":"rodriguez","children":[]}"elias" 的兄弟
  • 非常感谢!感谢所有帮助过的人。
【解决方案2】:

这是一个迭代对象并使用回溯删除具有给定名称的所需节点的提议。

此解决方案保留原始对象并使用短路来防止不必要的迭代。

它也使用recusion。

function deleteFromTree(o, name) {
    function getNode(a, i) {
        if (a.name === name) {
            index = i;
            return true;
        }
        if (Array.isArray(a.children) && a.children.some(getNode)) {
            if (~index) {
                a.children.splice(index, 1);
                index = -1;
            }
            return true;
        }
    }

    var index = -1;
    [o].some(getNode);
}

var tree = { "children": [{ "name": "bob", "children": [{ "name": "sam", "children": [{ "name": "mike", "children": [{ "name": "elias", "children": [] }, { "name": "rodriguez", "children": [] }] }] }] }] };

deleteFromTree(tree, 'sam');
document.write('<pre>' + JSON.stringify(tree, 0, 4) + '</pre>');

【讨论】:

    【解决方案3】:

    主要的“子”是一个包含嵌套子数组的数组。如何 我可以从这样的数组中删除一个对象吗?可以说我想 删除名称为“sam”的对象,这应该让我留下 以下:

    {
        "children": [{
            "name": "bob",
            "children": []
        }]
    }
    

    您可以利用JSON.stringify() replacer 参数从返回的JSON 字符串中删除属性

    replacer 可选
    一个改变字符串化过程行为的函数,或者一个字符串和数字对象数组 作为选择值对象属性的白名单 要包含在 JSON 字符串中。如果此值为 null 或不是 提供,对象的所有属性都包含在结果中 JSON 字符串。

    替换参数

    replacer 参数可以是函数或数组。作为一个 函数,它有两个参数,键和值是 字符串化。找到密钥的对象被提供为 replacer 的这个参数。最初它被一个空键调用 表示被字符串化的对象,然后调用它 被字符串化的对象或数组的每个属性。它应该 返回应该添加到 JSON 字符串的值,如下所示:

    • 如果返回Number,则与该数字对应的字符串将用作添加到 JSON 时的属性值 字符串。

    • 如果您返回 String,则在将其添加到 JSON 字符串时,该字符串将用作属性值。

    • 如果您返回 Boolean,则在将其添加到 JSON 时,酌情使用“true”或“false”作为属性值 字符串。

    • 如果您返回任何其他对象,该对象将递归地字符串化为 JSON 字符串,调用替换函数 每个属性,除非对象是函数,在这种情况下 没有向 JSON 字符串添加任何内容。

    • 如果返回 undefined,则该属性不包含在输出 JSON 字符串中。

      注意:您不能使用替换函数从 大批。如果返回 undefined 或函数,则使用 null 而是。


    var prop = "name";
    var value = "sam";
    var res = JSON.stringify(data, function re(a, obj) {;
         return obj[prop] === value ? null : obj
      }, 2);
    
    console.log(res, JSON.parse(res));
    

    var data = {
      "children": [{
        "name": "bob",
        "children": [{
          "name": "sam",
          "children": [{
            "name": "mike",
            "children": [{
              "name": "elias",
              "children": []
            }, {
              "name": "rodriguez",
              "children": []
            }]
          }]
        }]
      }]
    };
    
    var prop = "name";
    var value = "sam";
    var res = JSON.stringify(data, function re(a, obj) {;
         return obj[prop] === value ? null : obj
      }, 2);
    
    console.log(res, JSON.parse(res));
    
    document.querySelector("pre").textContent = res;
    <pre>
    </pre>

    【讨论】:

    • 我什么都没看到(ie11)
    • @NinaScholz 有趣。好久没试过ie浏览器了。 console 记录的任何错误?试过火狐,铬/铬浏览器? for 循环内的 console.log(b, b[curr[prop]]) 记录了什么?
    • var curr = Object.keys(b); Object.keys: Das Argument ist kein Objekt 转换为 'argument is no object'
    • 尝试将条件调整为if (b &amp;&amp; typeof b === "object") ?什么是 b 错误?
    • 对不起,该睡觉了。但现在它完美无缺。顺便说一句,在递归迭代器中使用构建是一个棘手的想法。
    【解决方案4】:

    您可以使用JSON.stringify()JSON.parse()String.prototype.match()RegExp /\{"name":"sam".*(?=\]\}\]\})/ 来匹配具有属性"name" 和值"sam" 的属性删除字符串的剩余部分,直到]}]} 是字符串的一部分String.prototype.replace()

    var res = JSON.parse(
      JSON.stringify(data)
      .replace(JSON.stringify(data).match(/\{"name":"sam".*(?=\]\}\]\})/)[0]
      , ""
      , ["children"])
    );
    

    var data = {
    
      "children": [{
        "name": "bob",
        "children": [{
          "name": "sam",
          "children": [{
            "name": "mike",
            "children": [{
              "name": "elias",
              "children": []
            }, {
              "name": "rodriguez",
              "children": []
            }]
          }]
        }]
      }]
    }
    
    var res = JSON.parse(
      JSON.stringify(data)
      .replace(JSON.stringify(data).match(/\{"name":"sam".*(?=\]\}\]\})/)[0]
      , ""
      , ["children"])
    );
    
    console.log(data)
    
    document.querySelector("pre").textContent = JSON.stringify(res, null, 2);
    <pre>
    </pre>

    【讨论】:

    • 这正是不这样做的方法。
    • @georg 是的,知道这一点,虽然尝试很有趣
    • @georg RegExp (?=\]\}\]\}) 当然可以改进。也可以用JSON.stringify()s 函数代替RegExp 来调整结果字符串
    猜你喜欢
    • 2020-12-07
    • 2021-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-02
    • 2019-11-02
    • 2019-04-30
    相关资源
    最近更新 更多