chindit
chindit

Reputation: 1009

Delete an element in nested array

I have this structure in my JavaScript:

"treeData": [
  {
    "id": 29,
    "name": "Root",
    "children": [
      {
        "id": 30,
        "name": "Sub-Root",
        "children": [
          {
            "id": 31,
            "name": "Sub-Sub-Root"
          }
        ]
      }
    ]
  },
  {
    "id": 32,
    "name": "Root 2"
  }
]

I would like to remove, for example, object with ID 30 (so «Sub-Root» and its children «Sub-Sub-Root»).

Currently, I am working with this recursive method:

for (let i = 0; i < this.treeData.length; i++) {
    this.findNested(this.treeData[i], this.selected.id); // ID is string like «30»
}

 findNested = function (obj, value) {
    if (obj.id === value) {
        // delete not working
        //delete obj;
        obj = null; // Setting to null to delete
        console.log('Passed');
    }
    if (obj && obj.children && obj.children.length > 0) {
        for (let j = 0; j < obj.children.length; j++) {
            this.findNested(obj.children[j], value);
        }
    }
}

The problem is, even I set obj to null, my treeData object is not affected and I don't get why.

My question is: how can I remove and element (and all its sub-elements) from my treeData knowing only the value of the "id" element ?

Upvotes: 1

Views: 2372

Answers (3)

Skyler
Skyler

Reputation: 656

I have changed your code a litle bit, you have to keep track of the parent array and use Array.prototype.splice() to delete, take a look below,

for (let i = 0; i < this.treeData.length; i++) {
    this.findNested(this.treeData[i], this.treeData, this.selected.id, i); // ID is string like «30»
}

findNested = function (obj, parent, value, i) {
    if (obj.id === value) {
        parent.splice(i,1)
    }
    if (obj && obj.children && obj.children.length > 0) {
        for (let j = 0; j < obj.children.length; j++) {
            this.findNested(obj.children[j], obj.children, value, j);
        }
    }
}

Upvotes: 3

connexo
connexo

Reputation: 56753

Do the deleting using Array.prototype.splice() in your for-iteration. Make your findNested function only return the information if you found the match you were looking for.

for (let i = 0; i < treeData.length; i++) {
    if (findNested(treeData[i], selected.id)) {
        treeData.splice(i, 1);
    }
}

function findNested (obj, value) {
    let found = false;
    if (obj.id === value) {
        found = true        
    } else {
        if (obj && obj.children && obj.children.length > 0) {
            for (let j = 0; j < obj.children.length; j++) {
                findNested(obj.children[j], value);
            }
        }
    }
    return found;
}

Upvotes: 2

Suttikeat Witchayakul
Suttikeat Witchayakul

Reputation: 187

The obj is passed in findNested by value not by reference, So everything you do with obj in the function will not affect the this.treeData.

Upvotes: 1

Related Questions