marcos
marcos

Reputation: 95

Delete all children in objects array

var arr = [{
  "id": "1",
  "name": "News",
}, {
  "id": "3",
  "parent": "1",
  "name": "News 2"
}, {
  "id": "5",
  "parent": "3",
  "name": "News",
}, {
  "id": "7",
  "parent": "5",
  "name": "News 2"
}, {
  "id": "15",
  "name": "News 2"
}, {
  "id": "20",
  "name": "News 2"
}];

var deleted_id = 1;

for (var i = 0; i < arr.length; i++) {
  if (arr[i].parent == deleted_id) {
    arr.splice(i, 1);
  } else continue;
}

I need to delete item (e.g. With id: "1"). Also I need to delete all levels children, who has "parent" field the same as id of deleted item.

Pay attention that item with id: 3 - is parent for item with id: 5, and item with id: 5 is parent for item with id: 7. They all - should be deleted as well.

There are some deep levels, therefore, result should be:

[{
  "id": "15",
  "name": "News 2"
}, {
  "id": "20",
  "name": "News 2"
}]

Upvotes: 3

Views: 144

Answers (5)

Nina Scholz
Nina Scholz

Reputation: 386736

This proposal builds a tree first and the gets an array with the id to delete. Then apply filter and get only the one who are not in the list.

var arr = [{ "id": "1", "name": "News", }, { "id": "3", "parent": "1", "name": "News 2" }, { "id": "5", "parent": "3", "name": "News", }, { "id": "7", "parent": "5", "name": "News 2" }, { "id": "15", "name": "News 2" }, { "id": "20", "name": "News 2" }],
    id = '1',
    idsToDelete = function (data) {
        var tree = {}, ids = {};
        data.forEach(function (a, i) {
            tree[a.id] = { id: a.id, children: tree[a.id] && tree[a.id].children };
            if (a.parent) {
                tree[a.parent] = tree[a.parent] || {};
                tree[a.parent].children = tree[a.parent].children || [];
                tree[a.parent].children.push(tree[a.id]);
            }
        });
        [tree[id]].forEach(function iter(a) {
            ids[a.id] = true;
            a.children && a.children.forEach(iter);
        });
        return ids;
    }(arr);

arr = arr.filter(function (a) { return !idsToDelete[a.id]; });

console.log(arr);

Upvotes: 1

Peter Seliger
Peter Seliger

Reputation: 13432

var
    arr = [{
        "id": "1",
        "name": "News"
    }, {
        "id": "3",
        "parent": "1",
        "name": "News 2"
    }, {
        "id": "5",
        "parent": "3",
        "name": "News"
    }, {
        "id": "7",
        "parent": "5",
        "name": "News 2"
    }, {
        "id": "15",
        "name": "News 2"
    }, {
        "id": "20",
        "name": "News 2"
    }];


arr = arr.reduce(function collectItemsBySkippingIds (collector, item) {
    var
        unskippedItemList = collector.unskippedItemList,
        skipItemByIdList  = collector.skipItemByIdList,

        isSkipViaId     = (skipItemByIdList.indexOf(item.id)      >= 0),
        isSkipViaParent = (skipItemByIdList.indexOf(item.parent)  >= 0);

    if (isSkipViaId || isSkipViaParent) {
        if (isSkipViaParent) {
            skipItemByIdList.push(item.id);
        }
    } else {
        unskippedItemList.push(item);
    }
    return collector;

}, {

    unskippedItemList : [],
    skipItemByIdList  : ["1"]

}).unskippedItemList;


console.log("arr : ", arr);

Upvotes: 0

bjaksic
bjaksic

Reputation: 3313

Try this Fiddle: https://jsfiddle.net/58buvybn/

Here is the code:

var arr = [{
        "id": "1",
        "name": "News",
        }, {
        "id": "3",
        "parent": "1",
        "name": "News 2"
        }, {
        "id": "5",
        "parent": "3",
        "name": "News",
        }, {
        "id": "7",
        "parent": "5",
        "name": "News 2"
        }, {
        "id": "15",
        "name": "News 2"
        }, {
        "id": "20",
        "name": "News 2"
    }];

    var deleted_id = 1;
    var foundIds = [];
    var findIds = function(delId) {
        var item = arr.find(function(x) { 
            return x.id == delId;
        });

        if (foundIds.indexOf(item.id) === -1) {
            foundIds.push(item.id);            
        }

        var children = arr.filter(function(x) { 
            return x.parent == item.id;
        });

        children.forEach(function(it) {
            findIds(it.id);    
        });
    }
    findIds(deleted_id);
    var newArr = arr.filter(function(x) {
        return foundIds.indexOf(x.id) === -1;
    });
    console.log(newArr);

Upvotes: 1

Morteza Tourani
Morteza Tourani

Reputation: 3536

First you should find the hierarchy relation. then according to id you want to delete go for it's children and delete them with parent.

var arr = [{"id": "1", "name": "News", }, {"id": "3", "parent": "1", "name": "News 2"}, {"id": "5", "parent": "3", "name": "News", }, {"id": "7", "parent": "5", "name": "News 2"}, {"id": "15", "name": "News 2"}, {"id": "20", "name": "News 2"}];

console.clear();

var children = {};
arr.forEach(function (item) {
	if (item.parent)
		children[item.parent] = (children[item.parent] || []).concat(item.id);
});
function deleteItem(id) {
	if (children[id])
		children[id].forEach(deleteItem)
	var index = arr.findIndex(i => i.id === id);
	if (index >= 0)
		arr.splice(index, 1);
}

deleteItem('1')
console.log(arr);

Upvotes: 3

GIA
GIA

Reputation: 1716

This will work to you I guess.

var arr =  [{  
      id:1,
      name:"News",
   },
   {  
      id:3,
      parent:1,
      name:"News 2"
   },
 {  
      id:"5",
      parent:3,
      name:"News",
   },
   {  
      id:7,
      parent:5,
      name:"News 2"
   },
 {  
      id:15,
      name:"News 2"
   },
 {  
      id:20,
      name:"News 2"
   }];

var deleted_id = 5;

for (var i = 0; i < arr.length; i++) {
  if(arr[i].hasOwnProperty('parent')) {        
    if (arr[i].parent == deleted_id) {
      arr.splice(i, 1);
      arr.splice(arr[i].parent, 1);
    }
  } else continue;
}
console.log(arr);

Upvotes: 0

Related Questions