JS: Remove object from nested array and return parent array
16,919
Solution 1
var arr = [{"id":10,"name":"Parent Brand 1","parent":null,"author":1,"deleted_at":null,"created_at":"2017-02-02 09:55:51","updated_at":"2017-02-02 09:55:51","subBrands":[{"id":31,"name":"Sub Brand 6","parent":10,"author":1,"deleted_at":null,"created_at":"2017-02-02 11:24:49","updated_at":"2017-02-02 11:42:02"},{"id":32,"name":"Sub Brand 7","parent":10,"author":1,"deleted_at":null,"created_at":"2017-02-02 11:24:57","updated_at":"2017-02-02 11:42:18"},{"id":33,"name":"Sub Brand 8","parent":10,"author":1,"deleted_at":null,"created_at":"2017-02-02 11:25:04","updated_at":"2017-02-02 11:42:34"},{"id":34,"name":"Sub Brand 9","parent":10,"author":1,"deleted_at":null,"created_at":"2017-02-02 11:25:39","updated_at":"2017-02-02 11:42:43"},{"id":35,"name":"Sub Brand 10","parent":10,"author":1,"deleted_at":null,"created_at":"2017-02-02 11:25:46","updated_at":"2017-02-02 11:42:52"},{"id":36,"name":"Sub Brand 4","parent":10,"author":1,"deleted_at":null,"created_at":"2017-02-02 11:43:53","updated_at":"2017-02-02 11:43:53"}]},{"id":12,"name":"Parent Brand 2","parent":null,"author":1,"deleted_at":null,"created_at":"2017-02-02 09:56:16","updated_at":"2017-02-02 09:56:16","subBrands":[]},{"id":16,"name":"Brand no children","parent":null,"author":1,"deleted_at":null,"created_at":"2017-02-02 10:37:40","updated_at":"2017-02-02 10:37:40","subBrands":[]},{"id":37,"name":"Whoops brand","parent":null,"author":1,"deleted_at":null,"created_at":"2017-02-02 11:44:10","updated_at":"2017-02-02 11:44:10","subBrands":[]}];
var id = prompt("Id of subbrands to remove: ");
arr.forEach(function(o) {
o.subBrands = o.subBrands.filter(s => s.id != id);
});
console.log(arr);
Solution 2
You could iterate the parent part, and the children and if found splice the object.
var data = [{ id: 10, name: "Parent Brand 1", parent: null, author: 1, deleted_at: null, created_at: "2017-02-02 09:55:51", updated_at: "2017-02-02 09:55:51", subBrands: [{ id: 31, name: "Sub Brand 6", parent: 10, author: 1, deleted_at: null, created_at: "2017-02-02 11:24:49", updated_at: "2017-02-02 11:42:02" }, { id: 32, name: "Sub Brand 7", parent: 10, author: 1, deleted_at: null, created_at: "2017-02-02 11:24:57", updated_at: "2017-02-02 11:42:18" }, { id: 33, name: "Sub Brand 8", parent: 10, author: 1, deleted_at: null, created_at: "2017-02-02 11:25:04", updated_at: "2017-02-02 11:42:34" }, { id: 34, name: "Sub Brand 9", parent: 10, author: 1, deleted_at: null, created_at: "2017-02-02 11:25:39", updated_at: "2017-02-02 11:42:43" }, { id: 35, name: "Sub Brand 10", parent: 10, author: 1, deleted_at: null, created_at: "2017-02-02 11:25:46", updated_at: "2017-02-02 11:42:52" }, { id: 36, name: "Sub Brand 4", parent: 10, author: 1, deleted_at: null, created_at: "2017-02-02 11:43:53", updated_at: "2017-02-02 11:43:53" }] }, { id: 12, name: "Parent Brand 2", parent: null, author: 1, deleted_at: null, created_at: "2017-02-02 09:56:16", updated_at: "2017-02-02 09:56:16", subBrands: [] }, { id: 16, name: "Brand no children", parent: null, author: 1, deleted_at: null, created_at: "2017-02-02 10:37:40", updated_at: "2017-02-02 10:37:40", subBrands: [] }, { id: 37, name: "Whoops brand", parent: null, author: 1, deleted_at: null, created_at: "2017-02-02 11:44:10", updated_at: "2017-02-02 11:44:10", subBrands: [] }];
data.some(function (a) {
return a.subBrands.some(function (b, i, bb) {
if (b.id === 31) {
bb.splice(i, 1);
return true;
}
});
});
console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Solution 3
I nest two forEach
loops and return when the item has been found and removed:
let items = [{id: 1, subItems: [{id: 1}, {id: 2}]}];
const subItemToBeRemovedId = 1;
items.forEach((item) => item.subItems.forEach((subItem, index) => {
if (subItem.id === subItemToBeRemovedId) {
return item.subItems.splice(index, 1);
}
}));
console.log(items);
Solution 4
foreach seems to work:
var brands=[{id:10,name:"Parent Brand 1",parent:null,author:1,deleted_at:null,created_at:"2017-02-02 09:55:51",updated_at:"2017-02-02 09:55:51",subBrands:[{id:31,name:"Sub Brand 6",parent:10,author:1,deleted_at:null,created_at:"2017-02-02 11:24:49",updated_at:"2017-02-02 11:42:02"},{id:32,name:"Sub Brand 7",parent:10,author:1,deleted_at:null,created_at:"2017-02-02 11:24:57",updated_at:"2017-02-02 11:42:18"},{id:33,name:"Sub Brand 8",parent:10,author:1,deleted_at:null,created_at:"2017-02-02 11:25:04",updated_at:"2017-02-02 11:42:34"},{id:34,name:"Sub Brand 9",parent:10,author:1,deleted_at:null,created_at:"2017-02-02 11:25:39",updated_at:"2017-02-02 11:42:43"},{id:35,name:"Sub Brand 10",parent:10,author:1,deleted_at:null,created_at:"2017-02-02 11:25:46",updated_at:"2017-02-02 11:42:52"},{id:36,name:"Sub Brand 4",parent:10,author:1,deleted_at:null,created_at:"2017-02-02 11:43:53",updated_at:"2017-02-02 11:43:53"}]},{id:12,name:"Parent Brand 2",parent:null,author:1,deleted_at:null,created_at:"2017-02-02 09:56:16",updated_at:"2017-02-02 09:56:16",subBrands:[]},{id:16,name:"Brand no children",parent:null,author:1,deleted_at:null,created_at:"2017-02-02 10:37:40",updated_at:"2017-02-02 10:37:40",subBrands:[]},{id:37,name:"Whoops brand",parent:null,author:1,deleted_at:null,created_at:"2017-02-02 11:44:10",updated_at:"2017-02-02 11:44:10",subBrands:[]}];
brands.forEach(function(brand) {
brand.subBrands = brand.subBrands.filter(function(subBrand){
return subBrand.id != 31;
})
});
console.log(brands);
Author by
BarryWalsh
Updated on June 09, 2022Comments
-
BarryWalsh almost 2 years
How do I remove the object in my array subBrands that is nested inside another array where the id property of an object is = to 31. I'm trying to get the whole parent array back without that subBrand removed.
Array is:
[ { "id": 10, "name": "Parent Brand 1", "parent": null, "author": 1, "deleted_at": null, "created_at": "2017-02-02 09:55:51", "updated_at": "2017-02-02 09:55:51", "subBrands": [ { "id": 31, "name": "Sub Brand 6", "parent": 10, "author": 1, "deleted_at": null, "created_at": "2017-02-02 11:24:49", "updated_at": "2017-02-02 11:42:02" }, { "id": 32, "name": "Sub Brand 7", "parent": 10, "author": 1, "deleted_at": null, "created_at": "2017-02-02 11:24:57", "updated_at": "2017-02-02 11:42:18" }, { "id": 33, "name": "Sub Brand 8", "parent": 10, "author": 1, "deleted_at": null, "created_at": "2017-02-02 11:25:04", "updated_at": "2017-02-02 11:42:34" }, { "id": 34, "name": "Sub Brand 9", "parent": 10, "author": 1, "deleted_at": null, "created_at": "2017-02-02 11:25:39", "updated_at": "2017-02-02 11:42:43" }, { "id": 35, "name": "Sub Brand 10", "parent": 10, "author": 1, "deleted_at": null, "created_at": "2017-02-02 11:25:46", "updated_at": "2017-02-02 11:42:52" }, { "id": 36, "name": "Sub Brand 4", "parent": 10, "author": 1, "deleted_at": null, "created_at": "2017-02-02 11:43:53", "updated_at": "2017-02-02 11:43:53" } ] }, { "id": 12, "name": "Parent Brand 2", "parent": null, "author": 1, "deleted_at": null, "created_at": "2017-02-02 09:56:16", "updated_at": "2017-02-02 09:56:16", "subBrands": [] }, { "id": 16, "name": "Brand no children", "parent": null, "author": 1, "deleted_at": null, "created_at": "2017-02-02 10:37:40", "updated_at": "2017-02-02 10:37:40", "subBrands": [] }, { "id": 37, "name": "Whoops brand", "parent": null, "author": 1, "deleted_at": null, "created_at": "2017-02-02 11:44:10", "updated_at": "2017-02-02 11:44:10", "subBrands": [] } ]
What I'm trying to get is:
[ { "id": 10, "name": "Parent Brand 1", "parent": null, "author": 1, "deleted_at": null, "created_at": "2017-02-02 09:55:51", "updated_at": "2017-02-02 09:55:51", "subBrands": [ { "id": 32, "name": "Sub Brand 7", "parent": 10, "author": 1, "deleted_at": null, "created_at": "2017-02-02 11:24:57", "updated_at": "2017-02-02 11:42:18" }, { "id": 33, "name": "Sub Brand 8", "parent": 10, "author": 1, "deleted_at": null, "created_at": "2017-02-02 11:25:04", "updated_at": "2017-02-02 11:42:34" }, { "id": 34, "name": "Sub Brand 9", "parent": 10, "author": 1, "deleted_at": null, "created_at": "2017-02-02 11:25:39", "updated_at": "2017-02-02 11:42:43" }, { "id": 35, "name": "Sub Brand 10", "parent": 10, "author": 1, "deleted_at": null, "created_at": "2017-02-02 11:25:46", "updated_at": "2017-02-02 11:42:52" }, { "id": 36, "name": "Sub Brand 4", "parent": 10, "author": 1, "deleted_at": null, "created_at": "2017-02-02 11:43:53", "updated_at": "2017-02-02 11:43:53" } ] }, { "id": 12, "name": "Parent Brand 2", "parent": null, "author": 1, "deleted_at": null, "created_at": "2017-02-02 09:56:16", "updated_at": "2017-02-02 09:56:16", "subBrands": [] }, { "id": 16, "name": "Brand no children", "parent": null, "author": 1, "deleted_at": null, "created_at": "2017-02-02 10:37:40", "updated_at": "2017-02-02 10:37:40", "subBrands": [] }, { "id": 37, "name": "Whoops brand", "parent": null, "author": 1, "deleted_at": null, "created_at": "2017-02-02 11:44:10", "updated_at": "2017-02-02 11:44:10", "subBrands": [] } ]
I'm open to using underscores. The closest I'm come is:
var brands = _.filter(brands, function(n) { return _.some(n.subBrands, function(subBrand){ return subBrand.id != brand.id; }); });
But that removes the arrays that don't contain a subBrand with an id of 31. So it's not very close to what I need.
Cheers!
-
ibrahim mahrir about 7 yearsThis will remove the match subBrands of only the first found object that contained them. Consider
arr = [{sb: [id:31]}, {sb: [id:31]}, {sb: [id:31]}]
will remove only the first object found bysome
. -
Nina Scholz about 7 years@ibrahimmahrir, i am assuming all
id
are unique. no need to filter all sub array. this generates new references, which are not necessary. save the environment. -
ibrahim mahrir about 7 yearsI'm not talking about the subBrands array itself (those ID should be unique). I'm talking about different objects that contain a subBrand array.
-
ibrahim mahrir about 7 yearsPlus this is not a typlical use of
some
. It should be used just to check if an item match some criteria or not (as lookahead for other stuff). -
guest271314 about 7 years@ibrahimmahrir "Plus this is not a typlical use of some. It should be used just to check if an item match some criteria or not (as lookahead for other stuff)." ? What do you mean by "should be used"? There are no restrictions on use of
Array.prototype
methods for different tasks. -
Nina Scholz about 7 yearsyou create all new reference by filtering an array. this looks a bit over the top for this purpose, even if there is not an object with the wanted id, you yield a new array.
-
guest271314 about 7 yearsWhy should a new array be created at each iteration at
.forEach()
, where requirement is to remove an object from existing array? -
ibrahim mahrir about 7 years@NinaScholz @guest271314 If you consider that the only other approach is to call
forEach
andsplice
on each found element, this will be the best. -
guest271314 about 7 years@ibrahimmahrir "If you consider that the only other approach is to call
forEach
andsplice
on each found element, this will be the best." That is not the only other possible approach. That is the pattern that you have selected to use. What do you mean by "best"? Creating a new array is not necessary to achieve expected result of removing an object from an existing array. -
Nina Scholz about 7 years@BarryWalsh, i don't know, if i am the right person, my proposal is below, but anyway do you need one original array and another without the specific id? or just one?
-
BarryWalsh about 7 years@ibrahimmahrir I'm seeing something a bit odd so just want to make sure it isn't coming from something in your answer. For some reason when I run that it overwrites the value of two different arrays with the same value. So I have two variables with the same value initially, one will store the filtered version. But when I run that function without referencing the other variable both are updated. It's really weird – BarryWalsh 9 mins ago
-
BarryWalsh about 7 years@NinaScholz whoops, sorry about that. I'll try that now cheers!
-
ibrahim mahrir about 7 years@BarryWalsh you want the result to be stored in a new array and not overriding the original?