javascript - 在javascript中从数组中删除对象元素

标签 javascript recursion internet-explorer-8 tree

我有一个未确定级别的 json 树,如下所示:

var nodeset = {
    "name" : "FORM",
    "attributes" : {
        "IDFORM" : "59",
        "NOMDOC" : "1",
        "VERSFORM" : "1.01",
        "DATEREPORT" : "10.10.1988"
    },
    "nodes" : [{
            "name" : "PART1",
            "persist" : true,
            "nodes" : [{
                    "name" : "FTYPE",
                    "persist" : true,
                    "value" : "1",
                    "weight" : 1
                }, {
                    "name" : "STARTDATE",
                    "persist" : true,
                    "value" : "01.10.2011",
                    "weight" : 1
                }, {
                    "name" : "ENDDATE",
                    "persist" : true,
                    "value" : "31.12.2011",
                    "weight" : 1
                }
            ],
            "value" : "31.12.2011",
            "weight" : 3
        }, {
            "name" : "PART2",
            "persist" : true,
            "nodes" : [{
                    "name" : "F203",
                    "persist" : true,
                    "value" : 12,
                    "weight" : 1
                }, {
                    "name" : "F204",
                    "persist" : true,
                    "value" : 12,
                    "weight" : 1
                }, {
                    "name" : "STI059DETAIL",
                    "persist" : false,
                    "nodes" : [{
                            "name" : "F1",
                            "persist" : false,
                            "value" : "asd",
                            "weight" : 1
                        }, {
                            "name" : "F2",
                            "persist" : false,
                            "value" : "asd",
                            "weight" : 1
                        }, {
                            "name" : "F3",
                            "persist" : false,
                            "value" : 0,
                            "weight" : 0
                        }, {
                            "name" : "F4",
                            "persist" : false,
                            "value" : 0,
                            "weight" : 0
                        }
                    ],
                    "value" : 0,
                    "weight" : 2
                }, {
                    "name" : "STI059DETAIL",
                    "persist" : false,
                    "nodes" : [{
                            "name" : "F1",
                            "persist" : false,
                            "value" : null,
                            "weight" : 0
                        }, {
                            "name" : "F2",
                            "persist" : false,
                            "value" : null,
                            "weight" : 0
                        }, {
                            "name" : "F3",
                            "persist" : false,
                            "value" : 0,
                            "weight" : 0
                        }, {
                            "name" : "F4",
                            "persist" : false,
                            "value" : 0,
                            "weight" : 0
                        }
                    ],
                    "value" : 0,
                    "weight" : 0
                }, {
                    "name" : "STI059DETAIL",
                    "persist" : false,
                    "nodes" : [{
                            "name" : "F1",
                            "persist" : false,
                            "value" : null,
                            "weight" : 0
                        }, {
                            "name" : "F2",
                            "persist" : false,
                            "value" : null,
                            "weight" : 0
                        }, {
                            "name" : "F3",
                            "persist" : false,
                            "value" : 0,
                            "weight" : 0
                        }, {
                            "name" : "F4",
                            "persist" : false,
                            "value" : 0,
                            "weight" : 0
                        }
                    ],
                    "value" : 0,
                    "weight" : 0
                }
            ],
            "value" : 0,
            "weight" : 4
        }
    ],
    "weight" : 7
};

我的任务是从中删除 weight0 且存在 nodes 属性的所有节点。

由于它是一棵树,我尝试使用这样的递归函数:

function clean(index, owner){
    var node    = owner[index],
        weight  = node.weight;

    delete node.weight;

    if(typeof node.persist != 'undefined'){
        delete node.persist;
    }

    if(!node.nodes)return;

    if(!weight){
        owner.splice(index, 1);
    }

    for(var i = 0; i < node.nodes.length; i++){
        clean(i, node.nodes);
    }
}

for(var i = 0; i < nodeset.nodes.length; i++){
    clean(i, nodeset.nodes);
}

但是 splice() 不知怎的,并没有从那里删除任何东西。我已将其替换为 delete Owner[index],这会导致这些节点的位置出现 null 值(我不想在那里看到 :( )。

我的问题:为什么splice()函数没有按我的预期工作(不删除节点)?另外,我采取了正确的方法吗?如果没有,那么任何其他建议将不胜感激。

问候。

测试 fiddle HERE ,如果它能以某种方式有所帮助的话。

最佳答案

您可以使用Array.filterArray.forEach过滤掉权重为0的节点。首先,定义一个谓词:

var keepNode = function(node) {
    return !(node.weight == 0 && node.hasOwnProperty("nodes"));
};

然后是一个函数来清除不需要的子节点,然后递归剩余的子节点:

function clean(tree) {
    if (tree.nodes) {
         tree.nodes = tree.nodes.filter(keepNode);
         tree.nodes.forEach(clean);
    }
}

最后处理整个数据结构:

clean(nodeset);

几乎可以肯定有一种更优雅的方式在过滤时进行递归,但这应该可以完成工作。

编辑(因为我没有注意到 IE8 标签)

对于 IE8(不支持过滤器),您有多种选择。您可以使用 ES5 shim package它将大多数 EcmaScript 函数添加到旧版 JS 引擎中。或者,您可以使用此垫片(可在上面链接的 filter 文档页面的下方找到):

if (!Array.prototype.filter)
{
  Array.prototype.filter = function(fun /*, thisp*/)
  {
    "use strict";

    if (this == null)
      throw new TypeError();

    var t = Object(this);
    var len = t.length >>> 0;
    if (typeof fun != "function")
      throw new TypeError();

    var res = [];
    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in t)
      {
        var val = t[i]; // in case fun mutates this
        if (fun.call(thisp, val, i, t))
          res.push(val);
      }
    }

    return res;
  };
}

关于javascript - 在javascript中从数组中删除对象元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17561990/

相关文章:

javascript - 尝试使用 underscore.js 从该 json 中提取名称

Java处理stackoverflow并在stackoverflow报错后继续正常执行

vbscript - 使用 vbscript 在单独的进程中启动 Internet Explorer 8

javascript - .empty() 不在 $ ('#xxxx' ).click(xxx 但从直接 js 函数调用时工作正常

javascript - 引用错误: html2pdf is not defined (JSPDF)

javascript - 服务器端Cookies的访问

c# - int ref 参数是否被装箱?

javascript - 理解的递归偶数函数问题(Javascript)

css - IE8 上的 Bootstrap 3 错误行为

jquery - IE8 和 JQuery 的 trim()