Here i attached my json .
"mainSteps": [
{
"id": "9b3b64b4-d8a5-46d5-b464-066dc5c45dc3",
"name": "Main Step 1",
"steps": [
{
"name": "sub step 1.1"
},
{
"name": "sub step 1.2"
}
]
},
{
"name": "Main step 2"
"steps": [
{
"name": "sub step 2.1"
},
{
"name": "sub step 2.2"
}
],
},
{
"name": "Main Step 3",
"steps": [
{
"name": "sub step 3.1"
},
{
"name": "sub step 3.2"
}
],
}
]
am looking for the output like --> [Main Step 1, sub step 1.1 , sub step 1.2] ,[Main Step 2, sub step 2.1 , sub step 2.2] , [Main Step 3, sub step 3.1 , sub step 3.2] . I spend the whole day for this output but am getting output like [[Main Step 1,Main Step 2,Main Step 3,sub step 1.1,sub step 1.2....] Like that am getting different format's but am unable to get the actual output as i mentioned about , Can someone clarify me .
var dataProcess = {
parentProcess:[],
subProcess:[]
};
var steps = mainData.steps; // Steps Having the Full json data
var proc = [];
$scope.getSteps = function(steps) {
for (var i=0;i< steps.length;i++) {
dataProcess.parentProcess.push(steps[i].name);
for(var j=i;j<steps[i].steps.length;j++){
dataProcess.subProcess.push(steps[i].steps[j].name);
}
}
This is one of the way i tried ,
If you need ES5 syntax:
var details = mainSteps.map(function(step) {
return [ step.name ].concat((step.steps || []).map(function(substep){
return substep.name;
})
});
ES6 syntax:
var details = mainSteps.map(step =< [step.name].concat((step.steps || []).map(sub => sub.name));
If you need more recursion than one layer deep, you can use a function as the top level mapper, that calls itself.
May be you can do like this;
var mainSteps = [
{
"id": "9b3b64b4-d8a5-46d5-b464-066dc5c45dc3",
"name": "Main Step 1",
"steps": [
{
"name": "sub step 1.1"
},
{
"name": "sub step 1.2"
}
]
},
{
"name": "Main step 2",
"steps": [
{
"name": "sub step 2.1"
},
{
"name": "sub step 2.2"
}
],
},
{
"name": "Main Step 3",
"steps": [
{
"name": "sub step 3.1"
},
{
"name": "sub step 3.2"
}
],
}
],
mapped = mainSteps.map(e => [e.name, e.steps[0].name, e.steps[1].name]);
console.log(mapped);
this way, it's working with various length of array and sub arrays :
var results = mainSteps.map(x => [x.name].concat(x.steps.map(y => y.name)));
Simple solution using Array.map and Array.concat functions:
// supposing "obj" is your initial object
var dataProcess = obj.mainSteps.map(function (o) {
return [o.name].concat(o.steps.map(function(v){ return v.name; }));
});
console.log(JSON.stringify(dataProcess, 0, 4));
The output:
[
[
"Main Step 1",
"sub step 1.1",
"sub step 1.2"
],
[
"Main step 2",
"sub step 2.1",
"sub step 2.2"
],
[
"Main Step 3",
"sub step 3.1",
"sub step 3.2"
]
]
DEMO link
Related
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);
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.
I have the following JSON of structured, nested data.
[
{
"id": "2e270ad7-90aa-41da-bb57-a777448f5906",
"name": "First Level 1",
"childValues": [
{
"id": "4cecbd28-fd06-4c2a-9b57-33d4a298675c",
"name": "Second Level 1 "
},
{
"id": "09893799-e21c-498f-96b4-e63e366a3c18",
"name": "Second Level 2"
}
]
},
{
"id": "18889675-9d71-420e-84a6-3603af044b6c",
"name": "First Level 2",
"childValues": [
{
"id": "b7093ca1-5fed-4eb2-b934-637bfdc6c7da",
"name": "Second Level 3"
},
{
"id": "a3575212-1746-4dd3-ab52-4e37786c035c",
"name": "Second Level 4"
}
]
},
{
"id": "71113ffb-62f0-4d76-941f-974be3cd35cb",
"name": "First Level 3",
"childValues": [
{
"id": "160570a5-29aa-4fdb-bb16-d9d7637d0177",
"name": "Second Level 5",
"childValues": [
{
"id": "2df28cb9-9ac4-478c-a2a4-6dc5206c983b",
"name": "Third Level 1"
},
{
"id": "a974cfac-1e2c-461c-ab64-0f5dd9d1cf1e",
"name": "Third Level 2"
}
]
},
{
"id": "6e5947ea-2c47-4d2b-8ecd-6369c728e7db",
"name": "Second Level 6"
}
]
}
]
I am trying to extract an array of objects from this nested array structure based on a level of nesting. For instance, level 0 just gives me back all of the base object in the array, but if I ask for level 1, I am trying to get back an output of just the second level nested objects, under the childValues property, in a single array, like the following:
[
{
"id": "4cecbd28-fd06-4c2a-9b57-33d4a298675c",
"name": "Second Level 1 "
},
{
"id": "09893799-e21c-498f-96b4-e63e366a3c18",
"name": "Second Level 2"
},
{
"id": "b7093ca1-5fed-4eb2-b934-637bfdc6c7da",
"name": "Second Level 3"
},
{
"id": "a3575212-1746-4dd3-ab52-4e37786c035c",
"name": "Second Level 4"
},
{
"id": "160570a5-29aa-4fdb-bb16-d9d7637d0177",
"name": "Second Level 5",
"childValues": [
{
"id": "2df28cb9-9ac4-478c-a2a4-6dc5206c983b",
"name": "Third Level 1"
},
{
"id": "a974cfac-1e2c-461c-ab64-0f5dd9d1cf1e",
"name": "Third Level 2"
}
]
},
{
"id": "6e5947ea-2c47-4d2b-8ecd-6369c728e7db",
"name": "Second Level 6"
}
]
And if I ask for level 2, I should only get the third level objects:
[
{
"id": "2df28cb9-9ac4-478c-a2a4-6dc5206c983b",
"name": "Third Level 1"
},
{
"id": "a974cfac-1e2c-461c-ab64-0f5dd9d1cf1e",
"name": "Third Level 2"
}
]
The only thing I have figured out is how to completely flatten the structure recursively, but cant put my finger on how to extract a specific level.
private flat(array: any[]) {
let result: any[] = [];
array.forEach((a) => {
result.push(a);
if (Array.isArray(a.childValues)) {
result = result.concat(this.flat(a.childValues));
}
});
return result;
}
Here's a cleaner version of Shane Padgett's function:
const getArrayByNthLevel = (array, levelToGet, currentLevel=0) => array.reduce((retval, a) => {
levelToGet === currentLevel
? retval.push(a)
: Array.isArray(a.childValues)
? retval = retval.concat(getArrayByNthLevel(a.childValues, levelToGet, currentLevel + 1))
: false
return retval;
}, []);
I was able to achieve this with the following function.
function getArrayByNthLevelOfPropName(array, propName, levelToGet, currentLevel = 0) {
let result = [];
array.forEach((a) => {
if (levelToGet === currentLevel) {
result.push(a);
}
if (Array.isArray(a[propName]) && levelToGet !== currentLevel) {
result = result.concat(getArrayByNthLevelOfPropName(a[propName], propName, levelToGet, ++currentLevel));
currentLevel -= 1;
}
});
return result;
}
You can use flatMap like this:
const input=[{id:"2e270ad7-90aa-41da-bb57-a777448f5906",name:"First Level 1",childValues:[{id:"4cecbd28-fd06-4c2a-9b57-33d4a298675c",name:"Second Level 1 "},{id:"09893799-e21c-498f-96b4-e63e366a3c18",name:"Second Level 2"}]},{id:"18889675-9d71-420e-84a6-3603af044b6c",name:"First Level 2",childValues:[{id:"b7093ca1-5fed-4eb2-b934-637bfdc6c7da",name:"Second Level 3"},{id:"a3575212-1746-4dd3-ab52-4e37786c035c",name:"Second Level 4"}]},{id:"71113ffb-62f0-4d76-941f-974be3cd35cb",name:"First Level 3",childValues:[{id:"160570a5-29aa-4fdb-bb16-d9d7637d0177",name:"Second Level 5",childValues:[{id:"2df28cb9-9ac4-478c-a2a4-6dc5206c983b",name:"Third Level 1"},{id:"a974cfac-1e2c-461c-ab64-0f5dd9d1cf1e",name:"Third Level 2"}]},{id:"6e5947ea-2c47-4d2b-8ecd-6369c728e7db",name:"Second Level 6"}]}];
const getLevel = (arr = [], required, current = 0) =>
required === current
? arr
: arr.flatMap(a => getLevel(a.childValues, required, current + 1))
console.log("Second Level: \n ", getLevel(input, 1))
console.log("Third Level: \n ", getLevel(input, 2))
If flatMap is not supported, you can use
[].concat(...arr.map(a => getLevel(a.childValues, required, current + 1)))
Following should work:
var data = [
{
"id": "2e270ad7-90aa-41da-bb57-a777448f5906",
"name": "First Level 1",
"childValues": [
{
"id": "4cecbd28-fd06-4c2a-9b57-33d4a298675c",
"name": "Second Level 1"
},
{
"id": "09893799-e21c-498f-96b4-e63e366a3c18",
"name": "Second Level 2"
}
]
},
{
"id": "18889675-9d71-420e-84a6-3603af044b6c",
"name": "First Level 2",
"childValues": [
{
"id": "b7093ca1-5fed-4eb2-b934-637bfdc6c7da",
"name": "Second Level 3"
},
{
"id": "a3575212-1746-4dd3-ab52-4e37786c035c",
"name": "Second Level 4"
}
]
},
{
"id": "71113ffb-62f0-4d76-941f-974be3cd35cb",
"name": "First Level 3",
"childValues": [
{
"id": "160570a5-29aa-4fdb-bb16-d9d7637d0177",
"name": "Second Level 5",
"childValues": [
{
"id": "2df28cb9-9ac4-478c-a2a4-6dc5206c983b",
"name": "Third Level 1"
},
{
"id": "a974cfac-1e2c-461c-ab64-0f5dd9d1cf1e",
"name": "Third Level 2"
}
]
},
{
"id": "6e5947ea-2c47-4d2b-8ecd-6369c728e7db",
"name": "Second Level 6"
}
]
}
];
function getData(data, targetLevel, currentLevel = 0) {
// If this is the target level, then extract the
// data we need from each item, and return the array
if (currentLevel == targetLevel) {
return data;
}
// Otherwise, run a map over the items, and if they have
// 'childValues', then recurs, but increment the value of
// 'current level' it will be iterating on
// Because 'map' will return array of array, merge them
// to a single array
return [].concat(...data.map(item => {
if (item.childValues) {
return getData(item.childValues, targetLevel, currentLevel + 1);
};
return [];
}));
}
document.getElementById("dataLevel0").innerHTML = JSON.stringify(getData(data, 0), null, 4);
document.getElementById("dataLevel1").innerHTML = JSON.stringify(getData(data, 1), null, 4);
document.getElementById("dataLevel2").innerHTML = JSON.stringify(getData(data, 2), null, 4);
<div>
Level 1:
</div>
<pre id="dataLevel0">
</pre>
<div>
Level 2:
</div>
<pre id="dataLevel1">
</pre>
<div>
Level 3:
</div>
<pre id="dataLevel2">
</pre>
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)
}
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()