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);

Share:
16,919
BarryWalsh
Author by

BarryWalsh

Updated on June 09, 2022

Comments

  • BarryWalsh
    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
    ibrahim mahrir about 7 years
    This 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 by some.
  • Nina Scholz
    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
    ibrahim mahrir about 7 years
    I'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
    ibrahim mahrir about 7 years
    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).
  • guest271314
    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
    Nina Scholz about 7 years
    you 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
    guest271314 about 7 years
    Why should a new array be created at each iteration at .forEach(), where requirement is to remove an object from existing array?
  • ibrahim mahrir
    ibrahim mahrir about 7 years
    @NinaScholz @guest271314 If you consider that the only other approach is to call forEach and splice on each found element, this will be the best.
  • guest271314
    guest271314 about 7 years
    @ibrahimmahrir "If you consider that the only other approach is to call forEach and splice 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
    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
    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
    BarryWalsh about 7 years
    @NinaScholz whoops, sorry about that. I'll try that now cheers!
  • ibrahim mahrir
    ibrahim mahrir about 7 years
    @BarryWalsh you want the result to be stored in a new array and not overriding the original?