Deleting a child from a nested object structure in JavaScript [duplicate] - javascript

In my application I create a JavaScript object based on a JSON similar to this:
{
name: "root",
id: 112,
children: [
{
name: "child one",
id: 231,
children: [
{name: "grand child 1", id: 334, children: []},
{name: "grand child 2", id: 784, children: []}
]
},
{
name: "child two",
id: 343,
children: []
}
]
}
How can I remove any Child by his id? Please note that I don’t know the static path to the node e.g id == 334 so I am wondering how I could remove that node with just knowing it's id.

function del(obj,id){
obj.children = obj.children.filter(el => {
if(el.children) del(el,id);//delete subnodes
return el.id !== id; //delete this
});
}
A recursive approach to traverse the objects, usable as:
del(
{ children:[ { id:1 }, { id:2, children:[{id:1}] }] },
1
);

check this :
var abc = your json object;
//now filter the item based on id
abc = jQuery.grep(
abc.children,
function (item,index) {
return item.id != "343";
});
hope it helps.

var delIt = function (obj,id) {
return obj.children = obj.children.filter(function (child) {
if(child.children) delIt(child,id);
return child.id!=id;
});
}
var x= delIt(Tobj,335);
You can use filter function to collect items which are not equals to given id

Related

Find elements with specific value in a nested array with unknown depth

I have an array with objects for which the nesting depth is unknown and can be different. An example of such an array looks like that:
let exampleArray = [
{
id: 'some-id',
label: "Item 1",
children: [
{
id: 'some-id',
label: "Child 1",
children: [
{
id: 'some-id', // How to find this for example?
label: "Child 2",
children: []
}
]
}
]
},
{
id: 'some-id',
label: "Item 2",
children: [
{
id: 'some-id',
label: "Child 1",
children: [
{
id: 'some-id',
label: "Child 2",
children: []
}
]
}
]
}
]
Each array item can have a nested array children. The basic structure is the same as the parent one.
The challenge
When I for example want to delete a nested element with a specific id, how could I do this? I think it would not be the best practice to start iterations with a static number of loops, because I don't know how big the array is nested.
If I know the ID from the children element, can I say something like: "Iterate the entire array including all nesting and find the element with the ID xy?".
Or what would be the best practice to handle such nested arrays?
A recursive function is likely what you're looking for:
function deleteById(data, id){
for(var x = 0; x < data.length; x++){
if(data[x].id === id){
data.splice(x, 1); // if it matches, remove it from the array
}
else{
deleteById(data[x].children, id);
}
}
}

Using ImmerJS to update child (by id) within a parent (by id)

How do I update the content of child12 using immerJS
const [fields, setFields] = useState([
{
name: "Parent 1",
id: "parent1",
children: [
{id:"child11", content=""},
{id:"child12", content=""}
],
},
{
name: "Parent 2",
id: "parent2",
children: [
{id:"child21", content=""},
{id:"child22", content=""}
],
},
]);
I have been able to achieve changing the parent name using the following:
setFields(
produce((draft) => {
const field = draft.find((field) => field.id === "parent1");
field[name] = "new parent1";
})
);
How do I go deeper, find within children the child by id and change its content value?
Turns out it is remarkably simple: just mutate the data.
setFields(
produce((draft) => {
const child = draft.find((field) => field.id === "parent1").children.find((child)=>child.id==="child21");
child[content] = "new value";
})
);

Object hierarchy from XML document using JavaScript

Given an XML document such as this:
<Root>
<Child1>
<ChildOfChild1_1>
<FinalChild> </FinalChild>
</ChildOfChild1_1>
<ChildOfChild1_2> </ChildOfChild1_2>
</Child1>
<Child2>
<ChildOfChild2_1> </ChildOfChild2_1>
</Child2>
<Child3> </Child3>
</Root>
I would like to return a object which has only two parameters, name and children. It would look like:
{
name: "Root"
children: [
{
name: "Child1"
children: [
{
name: "ChildOfChild1_1"
children:[
{
name: "FinalChild"
children: null
}
]
},
{
name: "ChildOfChild1_2"
children: null
}
]
},
{
name: "Child2"
children: [
{
name: "ChildOfChild2_1"
children: null
}
]
},
{
name: "Child3"
children: null
},
]
}
I do not care about node attributes, only nodeName and if they have children. I wrote code to get the first level of children but cannot wrap my head around the recursive part to get as deep as necessary. Thanks.
Below is what I have so far:
//assuming block is the root node and the root will at least have 1 child
let root = {
name = '',
children = []
};
root.name = block.nodeName;
for(let i=0 ; i<block.children.length ; i++) {
root.children.push(getChildren(block.children[i]));
}
function getChildren(data) {
let child = {};
child.name = data.nodeName;
child.children = []; //stuck here
return child;
}
The task is much simpler than you think.
You want a function that returns a node name and the list of node children, each of them processed in the exact same way:
function toObject(node) {
return {
name: node.nodeName,
children: [...node.children].map(toObject)
};
}
That's it.
const xmlDoc = new DOMParser().parseFromString(`<Root>
<Child1>
<ChildOfChild1_1>
<FinalChild> </FinalChild>
</ChildOfChild1_1>
<ChildOfChild1_2> </ChildOfChild1_2>
</Child1>
<Child2>
<ChildOfChild2_1> </ChildOfChild2_1>
</Child2>
<Child3> </Child3>
</Root>
`, "application/xml");
function toObject(node) {
return {
name: node.nodeName,
children: [...node.children].map(toObject)
};
}
const tree = toObject(xmlDoc.documentElement);
console.log(tree);
If you really want null when there are no children (an empty array is much easier to handle down the line, trust me), I'm sure you can make the necessary change in toObject yourself.

Identify circular dependency in a Json object and remove all element after 2 depth

I have a json object something like this:
var temp1 = {
name: "AMC",
children: [
{
name: "cde",
children: [
{
name: "AMC",
children: [
{
name: "cde",
children: [
{
name: "AMC",
children: [
//.............. continues as curcular depndency
]
}
]
}
]
}
]
},
{
name: "mnp",
children: [
{
name: "xyz",
children: []
}
]
}
]
}
Due to this cicular dependency, JSON.stringify is failing.
I have done enough google and searching to get the solution for this but could not find much help.
So here basically I want to detect a circular dependency in the json object and add a new key to the object, saying cricular: true and remove all the subsequent node.
So here is the result output what I am looking :
var temp1 = {
name: "AMC",
children: [
{
name: "cde",
circular: true,
children: [ // No children here as it is curcular dependency
]
},
{
name: "mnp",
children: [
{
name: "xyz",
children: []
}
]
}
]
}
There is a way, which I think can solve it, where I can loop through all the children unless there is no children upto maximum 2 levels, but that way I will miss valid children which are having depth more than 3.
I hope my question is clear. If not please let me know I will try to expand this further.
A recursive function solves this:
function check(stack,parent, obj){
stack = stack || []; //stack contains a list of all previously occurred names
var found = stack.find(function(parent){
return (parent==obj.name && obj.children.length>0); //checks to see if the current object name matches any in the stack.
});
if(!found && obj.children.length>0){
stack.push(obj.name); //adds the current object name to the list.
obj.children.forEach(function(child){
check(stack,obj, child);//recursively checks for all children.
})
}
else if(found){
parent.children=[];
parent.circular=true;
stack.pop(obj.name);
return;
}
else{
return;
}
}
check([],temp1, temp1)
This leads to alteration of the original object passed.
Hope this helps!
use console.table(circularObj) to help you in debugging

How to remove an nested JSON object using id

In my application I create a JavaScript object based on a JSON similar to this:
{
name: "root",
id: 112,
children: [
{
name: "child one",
id: 231,
children: [
{name: "grand child 1", id: 334, children: []},
{name: "grand child 2", id: 784, children: []}
]
},
{
name: "child two",
id: 343,
children: []
}
]
}
How can I remove any Child by his id? Please note that I don’t know the static path to the node e.g id == 334 so I am wondering how I could remove that node with just knowing it's id.
function del(obj,id){
obj.children = obj.children.filter(el => {
if(el.children) del(el,id);//delete subnodes
return el.id !== id; //delete this
});
}
A recursive approach to traverse the objects, usable as:
del(
{ children:[ { id:1 }, { id:2, children:[{id:1}] }] },
1
);
check this :
var abc = your json object;
//now filter the item based on id
abc = jQuery.grep(
abc.children,
function (item,index) {
return item.id != "343";
});
hope it helps.
var delIt = function (obj,id) {
return obj.children = obj.children.filter(function (child) {
if(child.children) delIt(child,id);
return child.id!=id;
});
}
var x= delIt(Tobj,335);
You can use filter function to collect items which are not equals to given id

Categories

Resources