admin管理员组文章数量:1293705
I have an array of objects in the below format:
{
"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"
}
]
}
]
}
Every object has a children element which contains the details of the element. I need to recursively iterate through the json object and remove all the nodes whose name
is empty string up till the root. For the above json format, the output should be like below:
{
"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"
}
]
}
]
}
How to do this in javascript recursively using Underscorejs.
I have an array of objects in the below format:
{
"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"
}
]
}
]
}
Every object has a children element which contains the details of the element. I need to recursively iterate through the json object and remove all the nodes whose name
is empty string up till the root. For the above json format, the output should be like below:
{
"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"
}
]
}
]
}
How to do this in javascript recursively using Underscorejs.
Share Improve this question edited Apr 6, 2016 at 6:50 RobG 148k32 gold badges179 silver badges214 bronze badges asked Apr 6, 2016 at 6:43 zilcuanuzilcuanu 3,71513 gold badges60 silver badges119 bronze badges 3- @RayonDabre—seems to me reduceRight and delete unwanted members is better, but does underscore.js have that? If not there's the built–in one. – RobG Commented Apr 6, 2016 at 6:48
- This SO question might help you – Aides Commented Apr 6, 2016 at 6:53
- I don't know how important it is for you to preserve the original data object but if you go array functions way you will probably lose it unless you clone the object in the first place by some means. – Redu Commented Apr 6, 2016 at 10:34
6 Answers
Reset to default 3This is a recursive solution with 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>");
Try this:
function condense(arr) {
arr.children = arr.children.map(function(c) {
c.children = c.children.filter(function(c1) {
return c1.name;
});
return c;
});
return arr;
}
I iterate through the children (with map
), then filter the children array with filter
. Only the children with a name not null or empty will be kept.
Here is a jsfiddle.
Not au fait with underscore.js. You can do this with ES5 reduceRight and delete members that you don't want, it should be more efficient than other approaches. The following uses recursion (which isn't as efficient as serial processing but is likely less code), so you can nest the objects as deep as you like:
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)));
This is very specific to your example.
Link to fiddle
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./ajax/libs/jquery/1.9.1/jquery.min.js"></script>
Probably not the shortest way, but it works:
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;
}
Fiddle: https://jsfiddle/gnmosu5p/2/
I know a recursive approach is asked but i can't help myself from giving a single liner here.
var newData = JSON.parse(JSON.stringify(data).replace(/{"name":"".+?},?/g, ""));
where data
is the initially given object to be restructured.
It's somewhat slower than array functions but one advantage of this method is preserving the original data object as it is while all array methods will override the original data object unless you clone it.
本文标签: condensing the array object recursively in javascriptStack Overflow
版权声明:本文标题:condensing the array object recursively in javascript - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741583043a2386682.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论