Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

remove object from nested array

I have a familytree looking like this:

{

    "children": [{
        "name": "bob",
        "children": [{
            "name": "sam",
            "children": [{
                "name": "mike",
                "children": [{
                    "name": "elias",
                    "children": []
                }, {
                    "name": "rodriguez",
                    "children": []
                }]
            }]
        }]
    }]
}

The main "children" is an array containing nested child-arrays. How can I remove an object from an array like this? Lets say I want to remove the object with the name "sam", that should leave me with the following:

{
    "children": [{
        "name": "bob",
        "children": []
    }]
}

Its the nesting that trips me up and i do not understand how to start.

Any help or directions to a tutorial that deals with similar issues are appreciated.

like image 769
eggman Avatar asked Mar 25 '16 21:03

eggman


3 Answers

Recursion is a good tool to work with trees.

var tree = {

    "children": [{
        "name": "bob",
        "children": [{
            "name": "sam",
            "children": [{
                "name": "mike",
                "children": [{
                    "name": "elias",
                    "children": []
                }, {
                    "name": "rodriguez",
                    "children": []
                }]
            }]
        }]
    }]
}

function removeFromTree(parent, childNameToRemove){
  parent.children = parent.children
      .filter(function(child){ return child.name !== childNameToRemove})
      .map(function(child){ return removeFromTree(child, childNameToRemove)});
  return parent;
}
tree = removeFromTree(tree, 'elias')         
console.log(tree);
document.write(JSON.stringify(tree));

This tutorial looks interesting (section "Binary Trees" and "Graphs"). I think it could help to implement your requirements: https://www.syncano.io/blog/data-structures-in-javascript/

like image 200
Meiko Rachimow Avatar answered Oct 19 '22 19:10

Meiko Rachimow


This is a proposal which iterates over the objects and uses backtracking for deleting the wanted node with the given name.

This solution keeps the original object and uses short circuit to prevent more than necessaray iterations.

It uses recusion as well.

function deleteFromTree(o, name) {
    function getNode(a, i) {
        if (a.name === name) {
            index = i;
            return true;
        }
        if (Array.isArray(a.children) && a.children.some(getNode)) {
            if (~index) {
                a.children.splice(index, 1);
                index = -1;
            }
            return true;
        }
    }

    var index = -1;
    [o].some(getNode);
}

var tree = { "children": [{ "name": "bob", "children": [{ "name": "sam", "children": [{ "name": "mike", "children": [{ "name": "elias", "children": [] }, { "name": "rodriguez", "children": [] }] }] }] }] };

deleteFromTree(tree, 'sam');
document.write('<pre>' + JSON.stringify(tree, 0, 4) + '</pre>');
like image 27
Nina Scholz Avatar answered Oct 19 '22 20:10

Nina Scholz


The main "children" is an array containing nested child-arrays. How can I remove an object from an array like this? Lets say I want to remove the object with the name "sam", that should leave me with the following:

{
    "children": [{
        "name": "bob",
        "children": []
    }]
}

You can utilize JSON.stringify() replacer parameter to remove properties from returned JSON string

replacer Optional
A function that alters the behavior of the stringification process, or an array of String and Number objects that serve as a whitelist for selecting the properties of the value object to be included in the JSON string. If this value is null or not provided, all properties of the object are included in the resulting JSON string.

The replacer parameter

The replacer parameter can be either a function or an array. As a function, it takes two parameters, the key and the value being stringified. The object in which the key was found is provided as the replacer's this parameter. Initially it gets called with an empty key representing the object being stringified, and it then gets called for each property on the object or array being stringified. It should return the value that should be added to the JSON string, as follows:

  • If you return a Number, the string corresponding to that number is used as the value for the property when added to the JSON string.

  • If you return a String, that string is used as the property's value when adding it to the JSON string.

  • If you return a Boolean,"true" or "false" is used as the property's value, as appropriate, when adding it to the JSON string.

  • If you return any other object, the object is recursively stringified into the JSON string, calling the replacer function on each property, unless the object is a function, in which case nothing is added to the JSON string.

  • If you return undefined, the property is not included in the output JSON string.

    Note: You cannot use the replacer function to remove values from an array. If you return undefined or a function then null is used instead.


var prop = "name";
var value = "sam";
var res = JSON.stringify(data, function re(a, obj) {;
     return obj[prop] === value ? null : obj
  }, 2);

console.log(res, JSON.parse(res));

var data = {
  "children": [{
    "name": "bob",
    "children": [{
      "name": "sam",
      "children": [{
        "name": "mike",
        "children": [{
          "name": "elias",
          "children": []
        }, {
          "name": "rodriguez",
          "children": []
        }]
      }]
    }]
  }]
};

var prop = "name";
var value = "sam";
var res = JSON.stringify(data, function re(a, obj) {;
     return obj[prop] === value ? null : obj
  }, 2);

console.log(res, JSON.parse(res));

document.querySelector("pre").textContent = res;
<pre>
</pre>
like image 1
guest271314 Avatar answered Oct 19 '22 19:10

guest271314