我有一个未确定级别的 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
};
我的任务是从中删除 weight
为 0
且存在 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.filter
和 Array.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/