我有以下格式的对象数组:
{
"country": "India",
"children": [
{
"name": "Karnataka",
"type": "State",
"children": [
{
"name": "",
"type": "city"
},
{
"name": "Bangalore",
"type": "city"
},
{
"name": "Mangalore",
"type": "city"
}
]
},
{
"name": "Kerala",
"type": "State",
"children": [
{
"name": "",
"type": "city"
}
]
},
{
"name": "Maharashtra",
"type": "State",
"children": [
{
"name": "Mumbai",
"type": "city"
},
{
"name": "Pune",
"type": "city"
}
]
}
]
}
每个对象都有一个子元素,其中包含元素的详细信息。我需要递归遍历 json 对象并删除其name
为空字符串直到根目录的所有节点。对于上面的json格式,输出应如下所示:
{
"country": "India",
"children": [
{
"name": "Karnataka",
"type": "State",
"children": [
{
"name": "Bangalore",
"type": "city"
},
{
"name": "Mangalore",
"type": "city"
}
]
},
{
"name": "Kerala",
"type": "State",
"children": [
]
},
{
"name": "Maharastra",
"type": "State",
"children": [
{
"name": "Mumbai",
"type": "city"
},
{
"name": "Pune",
"type": "city"
}
]
}
]
}
如何使用Underscorejs以递归方式在javascript中执行此操作。
答案 0 :(得分:3)
这是Array#filter()
的递归解决方案。
function filterName(a) {
if (a.name) {
if (Array.isArray(a.children)) {
a.children = a.children.filter(filterName);
}
return true;
}
}
var object = { "country": "India", "children": [{ "name": "Karnataka", "type": "State", "children": [{ "name": "", "type": "city" }, { "name": "Bangalore", "type": "city" }, { "name": "Mangalore", "type": "city" }] }, { "name": "Kerala", "type": "State", "children": [{ "name": "", "type": "city" }] }, { "name": "Maharashtra", "type": "State", "children": [{ "name": "Mumbai", "type": "city" }, { "name": "Pune", "type": "city" }] }] };
object.children.forEach(filterName);
document.write("<pre>" + JSON.stringify(object, 0, 4) + "</pre>");
答案 1 :(得分:1)
试试这个:
function condense(arr) {
arr.children = arr.children.map(function(c) {
c.children = c.children.filter(function(c1) {
return c1.name;
});
return c;
});
return arr;
}
我遍历子项(使用map
),然后使用filter
过滤子数组。只保留名称不为null或为空的子项。
这是jsfiddle。
答案 2 :(得分:1)
不 au fait 。您可以使用ES5 reduceRight 执行此操作并删除您不想要的成员,它应该比其他方法更有效。以下使用递归(它不像串行处理那样有效,但代码可能更少),因此您可以根据需要嵌套对象:
function removeEmpty(obj) {
obj.children.reduceRight(function (acc, child, i) {
if (!child.name) {
obj.children.splice(i, 1);
} else if (child.children) {
removeEmpty(child);
}
return null;
}, null);
return obj;
}
// Test
var data = {
"country": "India",
"children": [
{
"name": "Karnataka",
"type": "State",
"children": [
{
"name": "",
"type": "city"
},
{
"name": "Bangalore",
"type": "city"
},
{
"name": "Mangalore",
"type": "city"
}
]
},
{
"name": "Kerala",
"type": "State",
"children": [
{
"name": "",
"type": "city"
}
]
},
{
"name": "Maharashtra",
"type": "State",
"children": [
{
"name": "Mumbai",
"type": "city"
},
{
"name": "Pune",
"type": "city"
}
]
}
]
}
document.write('Original:<br>' + JSON.stringify(data) + '<br><br>' +
'Modified:<br>' + JSON.stringify(removeEmpty(data)));
&#13;
答案 3 :(得分:1)
这是非常具体的例子。
var obj = {
"country": "India",
"children": [{
"name": "Karnataka",
"type": "State",
"children": [{
"name": "",
"type": "city"
}, {
"name": "Bangalore",
"type": "city"
}, {
"name": "Mangalore",
"type": "city"
}]
}, {
"name": "Kerala",
"type": "State",
"children": [{
"name": "",
"type": "city"
}]
}, {
"name": "Maharashtra",
"type": "State",
"children": [{
"name": "Mumbai",
"type": "city"
}, {
"name": "Pune",
"type": "city"
}]
}]
};
//Before
document.write("BEFORE: "+JSON.stringify(obj));
//After
document.write("AFTER: "+JSON.stringify(checkJSON(obj)));
function checkJSON(obj) {
$.each(obj.children, function(index, value) {
if ($.isArray(value.children)) {
$.each(value.children, function(index, value) {
if (value.name == '') {
delete value.name;
}
});
}
});
return obj;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
答案 4 :(得分:1)
可能不是最短的方式,但它有效:
obj.children = _.each(obj.children, filter);
function filter(child, index, arr) {
if (child && child.name === '') {
// remove the ones without name
arr.splice(index, 1);
} else if (_.has(child, 'children')) {
// remove nested children
child.children = _.each(child.children, filter);
// check for empty children array and remove it (if needed)
/*
if (child.children.length === 0) {
delete child['children'];
}
*/
}
return child;
}
答案 5 :(得分:1)
我知道有一种递归的方法,但我不能帮助自己在这里提供一个班轮。
var newData = JSON.parse(JSON.stringify(data).replace(/{"name":"".+?},?/g, ""));
其中data
是最初要重组的对象。
它比数组函数稍慢,但这种方法的一个优点是保留了原始数据对象,而所有数组方法都将覆盖原始数据对象,除非你克隆它。