简体   繁体   English

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

[英]Remove object elements from array in javascript

I have a json tree with not determined level, which looks like this: 我有一个没有确定级别的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
};

My task is to remove all nodes from it where weight is 0 and where nodes property exists. 我的任务是从weight0且存在nodes属性的地方删除所有节点。

As it is a tree, I've tried to use recursive function like this: 因为它是一棵树,我试图使用这样的递归函数:

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

But splice() somehow, doesn't remove anything from there. splice()不知何故,并没有从那里删除任何东西。 I've replaced it with delete owner[index] , which causes null values on the place of those nodes (which I do not want to see there :( ). 我用delete owner[index]替换它,这会导致那些节点的位置为null值(我不想看到那里:( ))。

My questions: Why the splice() function not working as I expected (not deleting nodes)? 我的问题:为什么splice()函数不能正常工作(不删除节点)? Also, am I took a correct approach? 另外,我采取了正确的方法吗? If no, then any other suggestions would be appreciated. 如果不是,那么任何其他建议将不胜感激。

Regards. 问候。

Test fiddle HERE , if it might help somehow. 测试小提琴这里 ,如果它可以帮助莫名其妙。

You can use Array.filter and Array.forEach to filter out nodes with 0 weight. 您可以使用Array.filterArray.forEach过滤掉0权重的节点。 First, define a predicate: 首先,定义一个谓词:

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

Then a function to clean a node of unwanted children and then recurse on the remaining children: 然后是一个清除不想要的孩子的节点然后递归剩余孩子的函数:

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

Finally, process the entire data structure: 最后,处理整个数据结构:

clean(nodeset);

There's almost certainly a more elegant way that recurses as it filters, but this should do the job. 几乎可以肯定的是,在过滤时会有一种更优雅的方式,但这应该可以完成。

EDIT (because I didn't notice the IE8 tag) 编辑(因为我没注意到IE8标签)

For IE8 (which doesn't support filter ), you have a couple of choices. 对于IE8(不支持filter ),您有几个选择。 You can use the ES5 shim package that adds most EcmaScript functions to legacy JS engines. 您可以使用ES5填充程序包将大多数EcmaScript函数添加到旧版JS引擎中。 Alternatively, you can use this shim (available further down on the documentation page for filter linked above): 或者,您可以使用此垫片(可在上面链接的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;
  };
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM