How to remove an nested JSON object using id - 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";
})
);

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

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

How to update a JavaScript object with nested array and objects under n levels?

Following the below tree
let dumbTree = {
name: "vob",
uuid: "edbf146d-c9ee-4568-8c1e-a095f8ad4aff",
children: [
{
name: "A0A",
uuid: "8655460b-4862-4d11-800a-870482f4701b",
nodeType: "project",
children: []
},
{
name: "A1A",
uuid: "8655460b-4862-4d11-800a-870482f4701b",
nodeType: "project",
children: []
}
]
}
I'd like to convert incrementally path into the same kind of structure.
In that example, I've got a path /vob/A0A, and /vob/A1A, and then if I'm clicking on the leaf A1A, it'd give me an array like from an API call:
['/vob/A1A/A1A111', '/vob/A1A/A1A112', '/vob/A1A/A1A113'], so then I'd like to populate the tree accordingly
dumbTree = {
name: "vob",
uuid: "edbf146d-c9ee-4568-8c1e-a095f8ad4aff",
children: [
{
name: "A0A",
uuid: "8655460b-4862-4d11-800a-870482f4701b",
nodeType: "project",
children: []
},
{
name: "A1A",
uuid: "8655460b-4862-4d11-800a-870482f4701c",
nodeType: "project",
children: [
{
name: 'A1A111',
children: []
},
{
name: 'A1A112',
children: []
}
...
]
}
]
}
And then clicking on A1AAAA would give other children that will replace the empty array in A1A sub object, etc...
Is there any efficient way to do it?
I tried something with multiple finds on nested children, but this approach isn't going to be very effective on n levels.
const testChildren2 = [
{
name: "AAA123",
uuid: "00214ef8-fb29-4326-b236-3c90ab47eaaf",
children: []
}
]
let dumbTreeIndexA = dumbTree.children.findIndex((elt) => elt.name === 'AAA')
dumbTree.children[dumbTreeIndexA].children = testChildren2
// vobs/AAA/AAA123
const studyIndex = dumbTree.children[dumbTreeIndexA].children.findIndex((elt) => elt.name === 'AAA123')
I'm open to existing libraries such as lodash, ramdaJS, but didn't find a good way to do this yet.

Filter an array of objects with a second array with multiple values

I am trying to write a function to take the first object in the "parent" array, pull out the child field (which is in that array) and use that field to filter the second object called "child".
I want to get all the related records from the child object that are in the child field in the parent object.
Expected output
child: [
{
**id: 1,**
name: 'Jimmy Yukka',
},
{
**id: 2,**
name: 'Up North',
}
INPUT
Parent: [
{
**id: 1,**
name: 'Melbourne Bands',
**child: [1, 2]**
}
I have the following data
Parent: [
{
**id: 1,**
name: 'Melbourne Bands',
**child: [1, 2]**
},
{
id: 2,
name: 'Sydney Bands',
child: [3]
}
],
child: [
{
**id: 1,**
name: 'Jimmy Yukka',
},
{
**id: 2,**
name: 'Up North',
},
{
id: 3,
url: 'jimmyyukka.com',
name: 'INXS',
CreatedByUserId: 1
}
],
The code of the function I have implemented so far:
currentChildrenIds(ParentId, parentData, childData) {
const singleParentRecord = parentData.filter(function(parent) {
return parent.id === ParentId;
});
const parentsChildIds = singleParentRecord[0].books;
const childRecords = childData.filter(function(child) {
return child.id === parentsChildIds
});
return childRecords
}
NOTES
This bit here is where it is wrong
const childRecords = childData.filter(function(child) {
return child.id === parentsChildIds
This bit here is also a bit rubbish (hardcoding the [0])but not I'm not sure how I should be coding it correctly
const parentsChildIds = singleParentRecord[0].books;
here,
const childRecords = childData.filter(function(child) {
return child.id === parentsChildIds
parentsChildIds is a reference to an array: you don't want to test if an id is === to a a reference,
You have to be explicit and check if the id is contained in the array:
const childRecords = childData.filter(function(child) {
return parentsChildIds.includes(child.id)
Regarding the singleParentRecord[0] that does feel weird,
since you know the method filter will always return an array of size 1 or 0,
you can use the method find instead of filter
Also in functionnal programming (array functions such as filter, map, find...)
I advice you to read a bit about the arrow function syntax because:
The syntex is more dense and it makes it easier for your brain to understand when several functions are chained
If you want to use variables which are defined outside of the function it will be available only inside of an arrow function
your code with an arrow function:
const childRecords = childData.filter((child) => {
return child.id === parentsChildIds
}
Try this:
const Parent = [
{
id: 1,
name: 'Melbourne Bands',
child: [1, 2]
},
{
id: 2,
name: 'Sydney Bands',
child: [3]
}
];
const children = [
{
id: 1,
name: 'Jimmy Yukka',
},
{
id: 2,
name: 'Up North',
},
{
id: 3,
url: 'jimmyyukka.com',
name: 'INXS',
CreatedByUserId: 1
}
];
// We create a new array with Array.map
const result = Parent.map(parent => ({
// Spread properties of the parent
...parent,
// Override the child property and filter the children array with the `includes` method
child: children.filter(child => parent.child.includes(child.id)),
}))
console.log(result);

Categories

Resources