Reputation: 446
I have an array of objects that looks like this:
var data = [
{
type: "parent",
children: [
{
type: "parent",
children: [
{
type: "parent"
},
{
type: "parent",
children: [
{
type: "notParent"
},
{
type: "parent"
}
]
}
]
}
]
},
{
type: "parent",
children: [
{
type: "parent"
}
]
},
{
type: "parent",
children: [
{
type: "parent",
children: [
{
type: "parent"
},
{
type: "parent"
}
]
},
{
type: "notParent"
}
]
},
{
type: "notParent"
}
]
This data is an array of objects, and can have objects deeply nested. What I want to do is to create a new array that only contains the objects with the type: "parent" and remove all others. I am finding it hard to make this work for deeply nested objects. I have tried many variations of the following:
var findAllParents = function(obj, type) {
if(obj.type === type) { return obj; }
for(var i in obj) {
if(obj.hasOwnProperty(i)){
var foundParents = findAllParents(obj[i], type);
if(foundParents) { return foundParents; }
}
}
return null;
};
I would like for this to return data like this:
var data = [
{
type: "parent",
children: [
{
type: "parent",
children: [
{
type: "parent"
},
{
type: "parent",
children: [
{
type: "parent"
}
]
}
]
}
]
},
{
type: "parent",
children: [
{
type: "parent"
}
]
},
{
type: "parent",
children: [
{
type: "parent",
children: [
{
type: "parent"
},
{
type: "parent"
}
]
}
]
}
]
Only to return all objects with type: "parent"
Upvotes: 1
Views: 124
Reputation: 509
const data = [
{
type: "parent",
children: [
{
type: "parent",
children: [
{
type: "parent"
},
{
type: "parent",
children: [
{
type: "notParent",
children: [
{
type: "parent"
}
]
},
{
type: "parent"
}
]
}
]
}
]
},
{
type: "parent",
children: [
{
type: "parent"
}
]
},
{
type: "parent",
children: [
{
type: "parent",
children: [
{
type: "parent",
children: [
{
type: "parent",
children: [
{
type: "notParent"
}
]
}
]
},
{
type: "parent"
}
]
},
{
type: "notParent"
}
]
},
{
type: "notParent"
}
];
const filterCollectionItemsOfType = (collection, expectedType = 'parent') => {
const filteredCollection = collection.filter((item) => item.type === expectedType);
filteredCollection.forEach((item) => {
if (item.children && item.children.length) {
item.children = filterCollectionItemsOfType(item.children, expectedType);
}
});
return filteredCollection;
}
const parentsCollection = filterCollectionItemsOfType(data);
console.log(parentsCollection);
Upvotes: 1
Reputation: 36564
You can make a copy of the data
and then apply the recursive function which will remove the desired elements from the children
array of each object using filter()
var data = [ { type: "parent", children: [ { type: "parent", children: [ { type: "parent" }, { type: "parent" } ] } ] }, { type: "parent", children: [ { type: "parent" } ] }, { type: "parent", children: [ { type: "parent", children: [ { type: "parent" }, { type: "parent" } ] }, { type: "notParent" } ] } ]
function remove(obj){
if(obj.children){
obj.children = obj.children.filter(x => x.type === "parent");
obj.children.forEach(x => remove(x))
}
}
let copy = JSON.parse(JSON.stringify(data));
copy.forEach(x => remove(x));
console.log(copy)
Upvotes: 0