Getting Specific data from Nested Json which is having multiple Parent Children - javascript

Am trying to filter out some specific data's from Nested JSON which is having multiple Parent Children . Here is my json ,
[{
"id": "111111",
"name": "Parent",
"steps": [{
"id": "22222",
"name": "Child",
"steps": [{
"id": "333333",
"name": "Child -Child",
"steps": [{
"id": "444444",
"name": "Child - Child - Child",
"steps": [{
"id": "5555",
"name": "Child - Child - Child - Child"
}, {
"id": "522e9327-0747-4080-b6e2-d57e726b5b26",
"name": "Child - Child - Child - Child 2"
}],
}],
}],
}],
}]
What am trying to do here is i have to get some specific data's which are inside this nested json . For Ex : i need output like ["parent","Child","Child-Child"...etc ] . So i used map function using java script but the output was different like this one ["ParentChildChildChild"] (With No spaces) .If output's are String only mean's i can put "\n" and separate them but sometimes they are in Numbers so problem will occur's . Here is my Code which i tried ,
var myReturnedValues = mainSteps.map(x => [
x.steps.map(y => y.name +
y.steps.map(z => z.name +
z.steps.map(a => a.name + a.steps.map(b => b.name))
)
)
]);
Can someone help/clarify Me .

To achieve this most effectively you need To achieve this most effectively you need To achieve this most effectively you need to use recursion use recursion use recursion.
Using this pattern means that the array will always be filled no matter how many levels of nested object you have. Try this:
var data = [{
"id": "111111",
"name": "Parent",
"steps": [{
"id": "22222",
"name": "Child",
"steps": [{
"id": "333333",
"name": "Child -Child",
"steps": [{
"id": "444444",
"name": "Child - Child - Child",
"steps": [{
"id": "5555",
"name": "Child - Child - Child - Child"
}, {
"id": "522e9327-0747-4080-b6e2-d57e726b5b26",
"name": "Child - Child - Child - Child 2"
}],
}],
}],
}],
}]
var names = [];
function getNames(arr) {
for (var i = 0; i < arr.length; i++) {
names.push(arr[i].name);
if (arr[i].steps && arr[i].steps.length)
getNames(arr[i].steps);
}
}
getNames(data);
console.log(names);

You can achieve this using the javascript map function & recursion
var jsonArray = [{
"id": "111111",
"name": "Parent",
"steps": [{
"id": "22222",
"name": "Child",
"steps": [{
"id": "333333",
"name": "Child -Child",
"steps": [{
"id": "444444",
"name": "Child - Child - Child",
"steps": [{
"id": "5555",
"name": "Child - Child - Child - Child"
}, {
"id": "522e9327-0747-4080-b6e2-d57e726b5b26",
"name": "Child - Child - Child - Child 2"
}],
}],
}],
}],
}]
var namesArray = [];
var recur = function(obj) {
namesArray.push(obj.name);
if(obj.steps) {
obj.steps.map(recur);
}
}
jsonArray.map(recur);
console.log(namesArray);

You can also try
function getObjectKeyValues(obj, objKey) {
var result = [];
JSON.stringify(obj, function(key, value) {
if (key === objKey) {
result.push(value)
}
return;
});
return result;
}
Check:
MDN JSON.stringify()

Related

Adding data to a nested JSON object with children based on an array - Javascript/REACT

Hello stackoverflow community! I've been creating my own fullstack application for a while now, on the NEXTjs framework. This is going pretty well!! Unfortunately, I got stuck on a JSON import object for a treeview component. The treeview component must be populated using a specific nested structure, along with which treeview item should be selected on an initial render.
I managed to get the correct JSON object from the database, using a sql recursive tree function.
const jsonObject =
{
"id": "bfa3fdf8-4672-404e-baf5-0f9098a5705b",
"label": "main category 1",
"children": [
{
"id": "12e544bc-91b1-4e5d-bdbc-2163a5618305",
"label": "sub category 1.1",
"children": []
},
{
"id": "3f5e5cc7-f8b2-4d75-89e1-841c66d863e6",
"label": "sub category 1.2",
"children": [
{
"id": "903a727f-d94d-44ff-b2f6-a985fd167343",
"label": "sub category 1.2.1",
"children": []
},
{
"id": "fb344480-8588-4ce3-9662-f8e89069e4b4",
"label": "sub category 1.2.2",
"children": []
}
]
}
]
}
The problem is that this object, with categories needs to be updated with a 'checked: "true"' or 'checked: "false"' key value pair based on the existence in the referenceSelectedCategories array. And I don't know how to do this; maintaining the structure and object as needed.
const desiredOutputJsonObject =
{
"id": "bfa3fdf8-4672-404e-baf5-0f9098a5705b",
"label": "main category 1",
** "checked": "false",**
"children": [
{
"id": "12e544bc-91b1-4e5d-bdbc-2163a5618305",
"label": "sub category 1.1",
** "checked": "true",**
"children": []
},
{
"id": "3f5e5cc7-f8b2-4d75-89e1-841c66d863e6",
"label": "sub category 1.2",
** "checked": "false",**
"children": [
{
"id": "903a727f-d94d-44ff-b2f6-a985fd167343",
"label": "sub category 1.2.1",
** "checked": "false",**
"children": []
},
{
"id": "fb344480-8588-4ce3-9662-f8e89069e4b4",
"label": "sub category 1.2.2",
** "checked": "true",**
"children": []
}
]
}
]
}
const referenceSelectedCategories =
[
{
"categoryId": "12e544bc-91b1-4e5d-bdbc-2163a5618305",
"productId": "efed1c38-391b-4b5a-a9f1-91f3faec5f44",
"Id": "f82b0f63-3f39-486c-9157-5c7683b8e3b2"
},
{
"categoryId": "fb344480-8588-4ce3-9662-f8e89069e4b4",
"productId": "efed1c38-391b-4b5a-a9f1-91f3faec5f44",
"Id": "b2e8681b-eec4-404d-8f87-c6314db42e30"
}
]
I've read several stackoverflow questions, also searched for examples, but can't get it to work. Could someone help me out here?
Some extra information:
Code language I'm using is REACT on NEXTjs framework;
Treeview component could have a dept of max 5 levels;
The structure of the JSON object doesn't change, it's exactly as presented above.
The "id" in the JSON object corresponds to the "categoryId" in the array.
Do you need more information? :) Just ask, I'll provide you with the extra details!
Kind Regards,
Chris
A straight forward solution with recursive method. Done a quick test, working fine. If any issues found, please point it out.
const parentObj =
[
{
"categoryId": "12e544bc-91b1-4e5d-bdbc-2163a5618305",
"productId": "efed1c38-391b-4b5a-a9f1-91f3faec5f44",
"Id": "f82b0f63-3f39-486c-9157-5c7683b8e3b2"
},
{
"categoryId": "fb344480-8588-4ce3-9662-f8e89069e4b4",
"productId": "efed1c38-391b-4b5a-a9f1-91f3faec5f44",
"Id": "b2e8681b-eec4-404d-8f87-c6314db42e30"
}
]
const existingId = parentObj.map((item)=> (item.Id))
const childobj =
{
"id": "bfa3fdf8-4672-404e-baf5-0f9098a5705b",
"label": "main category 1",
"children": [
{
"id": "12e544bc-91b1-4e5d-bdbc-2163a5618305",
"label": "sub category 1.1",
"children": []
},
{
"id": "3f5e5cc7-f8b2-4d75-89e1-841c66d863e6",
"label": "sub category 1.2",
"children": [
{
"id": "903a727f-d94d-44ff-b2f6-a985fd167343",
"label": "sub category 1.2.1",
"children": []
},
{
"id": "f82b0f63-3f39-486c-9157-5c7683b8e3b2",
"label": "sub category 1.2.2",
"children": []
}
]
}
]
}
const childObj = [childobj]
const updateData=(obj)=> {
if(existingId.includes(obj.id)) obj['checked'] = true; else obj['checked'] = false
}
const traverse=(childObj)=> {
for(const obj of childObj) {
updateData(obj);
if(obj.children.length > 0) traverse(obj.children);
}
}
traverse(childObj);
Here you can ty this logic :
let desiredOutputJsonObject = {
id: "bfa3fdf8-4672-404e-baf5-0f9098a5705b",
label: "main category 1",
checked: false,
children: [
{
id: "12e544bc-91b1-4e5d-bdbc-2163a5618305",
label: "sub category 1.1",
checked: true,
children: [],
},
{
id: "3f5e5cc7-f8b2-4d75-89e1-841c66d863e6",
label: "sub category 1.2",
checked: false,
children: [
{
id: "903a727f-d94d-44ff-b2f6-a985fd167343",
label: "sub category 1.2.1",
checked: false,
children: [],
},
{
id: "fb344480-8588-4ce3-9662-f8e89069e4b4",
label: "sub category 1.2.2",
checked: true,
children: [
{
id: "fb344480-8588-4ce3-9662-f8e89069e4b9",
label: "sub category 1.2.2",
checked: false,
children: [],
},
],
},
],
},
],
};
let referenceSelectedCategories = [
{
categoryId: "12e544bc-91b1-4e5d-bdbc-2163a5618305",
productId: "efed1c38-391b-4b5a-a9f1-91f3faec5f44",
Id: "f82b0f63-3f39-486c-9157-5c7683b8e3b2",
},
{
categoryId: "fb344480-8588-4ce3-9662-f8e89069e4b4",
productId: "efed1c38-391b-4b5a-a9f1-91f3faec5f44",
Id: "b2e8681b-eec4-404d-8f87-c6314db42e30",
},
{
categoryId:"fb344480-8588-4ce3-9662-f8e89069e4b9",
productId: "efed1c38-391b-4b5a-a9f1-91f3faec5f44",
Id: "b2e8681b-eec4-404d-8f87-c6314db42e30",
},
];
let stack = [desiredOutputJsonObject];
while (stack.length) {
let desiredOutput = stack.pop();
if (desiredOutput.children) {
desiredOutput.children.forEach((node) => {
//get node whose id == category id
let result = referenceSelectedCategories.find(
(obj) => obj.categoryId === node.id
);
// while traversing if we get referenceSelectedCategories.categoryId ==desiredOutputJsonObject.id
if (result) {
node.checked = true;
}
// for traverse purpose
if (node.children.length) {
stack.push(node);
}
});
}
}
console.log(desiredOutputJsonObject);

How to add or update items in this multidimensional JSON?

Let's say we have some houses represented as JSON. Something like this:
[
{
"id": "1",
"code": "1",
"name": "Smith's",
"children": [
{
"id": "",
"code": "11",
"name": "Kitchen",
"children": [
{
"id": "",
"code": "111",
"name": "Sink",
"children": []
}
]
},
{
"id": "",
"code": "12",
"name": "Living Room",
"children": [
{
"id": "",
"code": "121",
"name": "Television",
"children": [
{
"id": "",
"code": "1211",
"name": "Panel buttons",
"children": [
{
"id": "",
"code": "12111",
"name": "Power button",
"children": []
},
{
"id": "",
"code": "12112",
"name": "Colors adjust button",
"children": []
}
]
},
{
"id": "",
"code": "1221",
"name": "Screen",
"children": []
}
]
}
]
}
]
},
{
"id": "2",
"code": "2",
"name": "Taylor's",
"children": [
// Here goes all house places and items like the example above
]
},
{
"id": "1",
"code": "1",
"name": "Wilson's",
"children": [
// Here goes all house places and items like the example above
]
}
]
Take notice that the "code" property, found in each item, is something to represent the "path" until that item, carrying its parents "code" property concatenated with its own position by incremental order. So the code "11" means house 1 and child 1. And 212 would be house 2, child 1, child 2. Also take notice that all items follow the same type. In other words, every item has a children that follows its own type. So, it could be infinite.
Now, I'd like to maintain these structure. Adding items, updating items and so on. Let's say we want to add a carpet in Smith's living room. We would go deep in the structure 2 levels, which are Smith's house (index 0 of the array) and living room (index 1 of the children array). And then add a carpet.
The problem is it won't be 2 levels in all cases. What if I wanted to add a bathroom? It would be level 1, alongside with kitchen in living room (the first children). What if I'd like to add a microwave in the kitchen and add to it buttons, display, etc?
I think I'm a recursive scenario where I have to visit all items and, if it is the one I'm looking to reach at, add/updated it.
I've tried following this example
I couldn't figure it out how to bring it to my case. though.
I appreciate if your contribution is in JavaScript, but feel free to represent it in other language in case you are better in other language =).
There are indeed some questions, like for instance what happens if you have more than 10 items as child and why do you need it?
And what happens if you remove any item on any level? will you recursively start updating all codes?
Nevertheless I gave it a go. In essence what I do in the code is first search for the parent (example: Kitchen) where you want to add it to and then add the new child item (example: Carpet) to it.
The search is a typical recursive search.
The child addition is a typical addition to an array.
For argument's sake I assumed that the fields code always exist and that children is always an array.
// Actual code is underneath the declaration of this array
let houseList = [
{
"id": "1",
"code": "1",
"name": "Smith's",
"children": [
{
"id": "",
"code": "11",
"name": "Kitchen",
"children": [
{
"id": "",
"code": "111",
"name": "Sink",
"children": []
}
]
},
{
"id": "",
"code": "12",
"name": "Living Room",
"children": [
{
"id": "",
"code": "121",
"name": "Television",
"children": [
{
"id": "",
"code": "1211",
"name": "Panel buttons",
"children": [
{
"id": "",
"code": "12111",
"name": "Power button",
"children": []
},
{
"id": "",
"code": "12112",
"name": "Colors adjust button",
"children": []
}
]
},
{
"id": "",
"code": "1221",
"name": "Screen",
"children": []
}
]
}
]
}
]
},
{
"id": "2",
"code": "2",
"name": "Taylor's",
"children": [
// Here goes all house places and items like the example above
]
},
{
"id": "1",
"code": "1",
"name": "Wilson's",
"children": [
// Here goes all house places and items like the example above
]
}
]
addChild(houseList,"11",{name:"Carpet" });
addChild(houseList,"1211",{name: "Volume Up Button"});
addChild(houseList,"1211",{name: "Volume Down Button"});
console.log('new houselist', houseList);
// child is just what you want to add and the parentCode refers to where you want to add it to
function addChild(houseList, parentCode, child) {
let parent = findInHouseList(houseList,parentCode,child);
let amountOfChildren = parent.children.length;
let newCodeName = parentCode +""+ (amountOfChildren+1);
child = {...{id: "", code: newCodeName, children: []}, ...child};
console.log('adding child ', child);
parent.children = [...parent.children, child];
}
function findInHouseList(houseList,code) {
for (let house of houseList) {
let foundElement = findElement(house,code);
if ( foundElement)
return foundElement;
}
}
function findElement(currentElement, code) {
if ( currentElement.code === code)
return currentElement;
if (currentElement.children?.length > 0)
{
for (let child of currentElement.children) {
let foundElement = findElement(child,code);
if ( foundElement)
return foundElement;
}
}
return null;
}
I decided to let the code manage the code names for new children. It seems the easiest.
What you're trying to do is updating a JSON value at a dynamic path.
This function will append a child to the item which holds the specified code.
You may add conditions to check if the item at the code is defined
function appendChild(houses, code, item) {
let path = code.split('')
let o = houses
for (let i = 0; i < path.length; i++) {
let n = path[i] - 1
o = o[n]["children"]
}
o.push(item)
return houses
}
However, you should start your code indexes at 0 and storing them inside the JSON is useless since they are simply the path to reach the item.

Best way to iterate hierarchical JSON/JS data

I'm hitting some performance issues with various implementations of this...
Essentially, I have a dataset of around 1500 objects in the below form: -
{
"Id": "411fc047-9d58-4faf-8da2-dfaf1fc3f3a3",
"ParentId": null,
"Name": "Main Location",
"Children": [
{
"Id": "3cb93d59-613c-4797-8858-bc3f31f6baa0",
"ParentId": "411fc047-9d58-4faf-8da2-dfaf1fc3f3a3",
"Name": "Site A",
"Children": [
{
"Id": "a1fec942-b425-4307-905d-9e2a6f8730b3",
"ParentId": "3cb93d59-613c-4797-8858-bc3f31f6baa0",
"Name": "Location A1",
"Children": [
{
"Id": "5538e976-db1c-49c2-8cab-70aafc1e4e70",
"ParentId": "a1fec942-b425-4307-905d-9e2a6f8730b3",
"Name": "Location A1 a",
"Children": []
},
{
"Id": "6f5a536f-4b4f-4a10-b7ba-657d772d0588",
"ParentId": "a1fec942-b425-4307-905d-9e2a6f8730b3",
"Name": "Location A1 b",
"Children": []
}
]
}
]
},
{
"Id": "319db987-994d-45d5-9023-8f21b8a589cb",
"ParentId": "411fc047-9d58-4faf-8da2-dfaf1fc3f3a3",
"Name": "Site B",
"Children": [
{
"Id": "f0c1f222-4118-4c07-b7be-30ff70fada03",
"ParentId": "319db987-994d-45d5-9023-8f21b8a589cb",
"Name": "Location B1",
"Children": [
{
"Id": "fe33043d-4cf2-498e-aa80-04848e109acb",
"ParentId": "f0c1f222-4118-4c07-b7be-30ff70fada03",
"Name": "Location B1 b",
"Children": []
},
{
"Id": "d92ae7d5-bc44-4e94-be75-0cda5a254664",
"ParentId": "f0c1f222-4118-4c07-b7be-30ff70fada03",
"Name": "Location B1 b",
"Children": [
{
"Id": "0a89ee4a-3b18-4772-baa3-fc0682d7053f",
"ParentId": "d92ae7d5-bc44-4e94-be75-0cda5a254664",
"Name": "Location B1 b Special Site...",
"Children": []
}
]
}
]
}
]
}
]
}
]
It has an unknown depth, as in the children can continue to exist on each object...
Firstly, I would love to know what would be the fastest way to search this to find one of the objects given an Id (GUID). I have tried all sorts, I've experimented with flattening it out and using ES6 .find() (instead of filter for singular results...), I've written a custom iterator that essentially starts at the top and works it's way through the children until a match is found... These solutions work, I'm just wondering if there's a trick I'm missing..?
One area this slows down is if I want to then climb the tree from the found object, so if I use the .find() approach, and I want to know all of it's parents, I then need to also find() each parent based on the ParentId...
Secondly, now this perhaps is a bit of a unique use case, but essentially, I populate a customised React Treeview in JS with this data, and in the treeview, each item has a checkbox... Once the user checks the box, I add the object Id attribute to a 'selected' array to track what has been selected and what hasn't...
Where this gets complicated, is I don't want to then select all of the parent items above it, but instead need to know their ids so I can store them in a 'partially selected' array to illustrate on the Treeview that they haven't been selected, but a child of it somewhere has... (I conditionally change the styling of the checkbox depending if it's a Selected or 'Partially Selected' checkbox...
This is the key area where the slowdown occurs, because the User might check only 3 or 4 checkboxes mid way down the tree, which will also check all of their children, and this these 'partially selected' ids need to be found for each 'fully' checked item in the tree...
Make sense? :-S
I'm wondering basically, is there some super duper fast way that people usually use when working with things like this or is the nature of it slow and that's that because I simply need to check each route individually..?
Thanks!
You could build a hash map and have a fast access to the wanted objects.
const
buildHashMap = (r, o) => {
r[o.Id] = o;
return o.Children
? o.Children.reduce(buildHashMap, r)
: r;
},
data = [{ Id: "411fc047-9d58-4faf-8da2-dfaf1fc3f3a3", ParentId: null, Name: "Main Location", Children: [{ Id: "3cb93d59-613c-4797-8858-bc3f31f6baa0", ParentId: "411fc047-9d58-4faf-8da2-dfaf1fc3f3a3", Name: "Site A", Children: [{ Id: "a1fec942-b425-4307-905d-9e2a6f8730b3", ParentId: "3cb93d59-613c-4797-8858-bc3f31f6baa0", Name: "Location A1", Children: [{ Id: "5538e976-db1c-49c2-8cab-70aafc1e4e70", ParentId: "a1fec942-b425-4307-905d-9e2a6f8730b3", Name: "Location A1 a", Children: [] }, { Id: "6f5a536f-4b4f-4a10-b7ba-657d772d0588", ParentId: "a1fec942-b425-4307-905d-9e2a6f8730b3", Name: "Location A1 b", Children: [] }] }] }, { Id: "319db987-994d-45d5-9023-8f21b8a589cb", ParentId: "411fc047-9d58-4faf-8da2-dfaf1fc3f3a3", Name: "Site B", Children: [{ Id: "f0c1f222-4118-4c07-b7be-30ff70fada03", ParentId: "319db987-994d-45d5-9023-8f21b8a589cb", Name: "Location B1", Children: [{ Id: "fe33043d-4cf2-498e-aa80-04848e109acb", ParentId: "f0c1f222-4118-4c07-b7be-30ff70fada03", Name: "Location B1 b", Children: [] }, { Id: "d92ae7d5-bc44-4e94-be75-0cda5a254664", ParentId: "f0c1f222-4118-4c07-b7be-30ff70fada03", Name: "Location B1 b", Children: [{ Id: "0a89ee4a-3b18-4772-baa3-fc0682d7053f", ParentId: "d92ae7d5-bc44-4e94-be75-0cda5a254664", Name: "Location B1 b Special Site...", Children: [] }] }] }] }] }],
hashmap = data.reduce(buildHashMap, {});
console.log(hashmap);
Had you tried a custom recursive function?
function findId(data, id) {
const { Id, Children } = data;
if(id === Id) return data;
if(! Children || Children.length === 0) return null;
for(let i = 0; i < Children.length; ++i) {
const ret = findId(Children[i], id);
if(ret) return ret;
}
return null;
}
Hope this helps.

Finding the position of super nested array of objects

I'm trying to find the exact position and access all properties of the super nested array of objects.
I'm struggling to create a function where if I give index number as input parameter it should give me it's position in the array and also access all the properties in return.
Here is the sample array of object
I'm OK with ES6 and above solution too
{
"name": "branch 1",
"index": 1,
"children": [{
"name": "sub child 1",
"index": 2,
"children": [{
"name": "subx2 child 1",
"index": 3,
"children": [{
"name": "subx3 child 1",
"index": 4,
"children": [{
"name": "subx4 child 1",
"index": 21
},
{
"name": "subx4 child 2",
"index": 18
}
]
},
{
"name": "subx3 child 2",
"index": 6,
"children": [{
"name": "subx4 child 1",
"index": 7
},
{
"name": "subx4 child 2",
"index": 21
}
]
},
{
"name": "subx3 child 3",
"index": 22
}
]
}]
},
{
"name": "sub child 2",
"index": 28
}
]
}
Yeah I know this json object is scary enough to spend time and solve. Any kind of help is greatly appriciated.
for example if my function name is findChildIndex(22) it should return me something like this x.children[0].children[0].children[2]
Thank you!
You could recursively collect the indexes in the children arrays that lead to the target index:
function findIndexNested(data, index) {
if (data.index === index) return [];
let result;
const i = (data.children || []).findIndex(child => {
return result = findIndexNested(child, index)
});
if (result) return [i, ...result];
}
function findByPath(data, path) {
for (let i of path) data = data.children[i];
return data
}
// Sample data
const data = {"name": "branch 1","index": 1,"children": [{"name": "sub child 1","index": 2,"children": [{"name": "subx2 child 1","index": 3,"children": [{"name": "subx3 child 1","index": 4,"children": [{"name": "subx4 child 1","index": 21},{"name": "subx4 child 2","index": 18}]},{"name": "subx3 child 2","index": 6,"children": [{"name": "subx4 child 1","index": 7},{"name": "subx4 child 2","index": 21}]},{"name": "subx3 child 3","index": 22}]}]},{"name": "sub child 2","index": 28}]}
const index = 22
const result = findIndexNested(data, index);
console.log("Found index " + index + " via these child indexes: " + result);
console.log("The object is", findByPath(data, result));
You could use recursion and check if children of the element exists use for loop to iterate to through all the children and recursively apply the function of each child
const obj = {
"name": "branch 1",
"index": 1,
"children": [{
"name": "sub child 1",
"index": 2,
"children": [{
"name": "subx2 child 1",
"index": 3,
"children": [{
"name": "subx3 child 1",
"index": 4,
"children": [{
"name": "subx4 child 1",
"index": 21
},
{
"name": "subx4 child 2",
"index": 18
}
]
},
{
"name": "subx3 child 2",
"index": 6,
"children": [{
"name": "subx4 child 1",
"index": 7
},
{
"name": "subx4 child 2",
"index": 21
}
]
},
{
"name": "subx3 child 3",
"index": 22
}
]
}]
},
{
"name": "sub child 2",
"index": 28
}
]
}
function find(obj,index){
if(obj.children){
for(let i = 0;i<obj.children.length;i++){
let x = find(obj.children[i],index);
if(x) return {...x,pos:i};
}
}
return obj.index === index ? obj : false;
}
console.log(find(obj,21))
If i got your question correctly, You can do something like this:
const func=(obj,index, nested=0)=>{
return Obj.index===index ? {obj, nested} : func(obj.children,index, nested+1)
}

How to store object at a certain level in the JSON data by dynamically iterating through it? [duplicate]

This question already has answers here:
How can I access and process nested objects, arrays, or JSON?
(31 answers)
Closed 5 years ago.
I have the following json:
{
"menu": [{
"name": "vegetation",
"id": "1",
"children": [
{
"name": "landuse",
"id": "1.1",
"children": [
{
"name": "forest area",
"id": "1.1.1",
"children": null
},
{
"name": "plantation",
"id": "1.1.2",
"children": null
}
]
}
]
}]
}
I want to dynamically access the objects whose value of "children" is null and store the "name" of these objects in a variable. For example in this case either forest area or plantation. How can I do this using javascript or jquery?
You don't need jQuery for this, a simple for will do and, most likely, it's faster than anything else:
var childless = [],
checkForChildren = function(items){
for (var i = 0; i < items.length; i++) {
if (items[i].children)
checkForChildren(items[i].children);
else
childless.push(items[i]);
}
};
// test it:
var menu = [{
"name": "vegetation",
"id": "1",
"children": [{
"name": "landuse",
"id": "1.1",
"children": [{
"name": "forest area",
"id": "1.1.1",
"children": null
},{
"name": "plantation",
"id": "1.1.2",
"children": null
}]
}]
}];
checkForChildren(menu);
console.log(childless);
Recursion comes to mind.
var childless = [];
var recursive_function = function(obj){
if(obj.children == null){
childless.push(obj);
} else {
$.each(obj.children, function(child){
recursive_function(child);
}
}
};
$.each(json_obj.menu, function(root_level){
recursive_function(root_level);
});
console.log(childless);
console.log($.map(childless, function(x){return x.name;}));
var test = {
"menu": [{
"name": "vegetation",
"id": "1",
"children": [{
"name": "landuse",
"id": "1.1",
"children": [{
"name": "forest area",
"id": "1.1.1",
"children": null
},
{
"name": "plantation",
"id": "1.1.2",
"children": null
}
]
}]
}]
};
var hasNullChildren = [];
function checkChildren ( children ) {
//loop over all children
children.forEach(function(child){
//if no children, add name to list
if (!child.children) hasNullChildren.push(child.name);
//check nested children
else checkChildren(child.children);
});
}
//start the recursion loop
checkChildren(test.menu);
console.log(hasNullChildren);
Recursively iterating through the array and searching for the children = null, gives the array with all the names of objects.
const obj = {
"menu": [{
"name": "vegetation",
"id": "1",
"children": [
{
"name": "landuse",
"id": "1.1",
"children": [
{
"name": "forest area",
"id": "1.1.1",
"children": null
},
{
"name": "plantation",
"id": "1.1.2",
"children": null
}
]
},{
"name": "landuse",
"id": "1.1",
"children": null
}
]
}]
}
function getNameWithNullChildren(arr) {
let array = [];
arr.forEach(item => {
if(item.children === null) {
array.push(item.name);
} else {
array = getNameWithNullChildren(item.children);
}
});
return array;
}
console.log(getNameWithNullChildren(obj.menu));

Categories