Extract data from json with 2 properties with same name - javascript

I have a complex deeply nested JSON in Node.js and I have trouble extracting certain data. I need all the ids that belong only to the items, my problem is that the folders also have an id field so I cannot access only the id from the items. This is an example json:
{
id: "0",
name: null,
parentId: null,
folderType: "chatCannedMessages",
folders: [
{
id: 3195588631115178,
name: "Testfolder",
parentId: null,
folderType: "chatCannedMessages",
folders: [
{
id: "3195588620182363",
name: "Subfolder",
parentId: "3195588631115178",
folderType: "chatCannedMessages",
folders: [
{
id: "3206824598737435",
name: "Interesting",
parentId: "3195588620182363",
folderType: "chatCannedMessages",
folders: [],
items: [
{
id: "3208409930553392",
name: "Canned Message",
folderId: "3206824598737435",
updated: "2022-05-27T07:28:40.450Z",
frontendFolderId: null,
text: "<p>This is an HTML with Image.</p>",
keywords: "test",
subject: "What kind of subject",
slashCommand: "test",
language: "en-US",
setupItemId: "3208409930553392",
},
],
},
],
items: [
{
id: "3195595211854821",
name: "Message in subfolder",
folderId: "3195588620182363",
updated: "2022-05-19T12:05:39.503Z",
frontendFolderId: null,
text: "Message in subfolder",
keywords: "test",
subject: "Message in subfolder",
slashCommand: "sub",
language: "bn-BD",
setupItemId: "3195595211854821",
},
],
},
],
items: [],
},
],
items: [
{
id: "2888102250465731",
name: "bye",
folderId: null,
updated: "2022-05-25T11:15:36.367Z",
frontendFolderId: null,
text: "Thanks for contacting us. Please do not hesitate to contact us again if we can be of further assistance.",
keywords: "bye",
subject: null,
slashCommand: null,
language: null,
setupItemId: "2888102250465731",
},
],
};
The output that I want to achieve here is an array, looking like this:
["3208409930553392", "3195595211854821", null]

Iterate it is not that complex json. Just items and folders.
var obj={id:"0",name:null,parentId:null,folderType:"chatCannedMessages",folders:[{id:0xb5a5ef534b5aa,name:"Testfolder",parentId:null,folderType:"chatCannedMessages",folders:[{id:"3195588620182363",name:"Subfolder",parentId:"3195588631115178",folderType:"chatCannedMessages",folders:[{id:"3206824598737435",name:"Interesting",parentId:"3195588620182363",folderType:"chatCannedMessages",folders:[],items:[{id:"3208409930553392",name:"Canned Message",folderId:"3206824598737435",updated:"2022-05-27T07:28:40.450Z",frontendFolderId:null,text:"<p>This is an HTML with Image.</p>",keywords:"test",subject:"What kind of subject",slashCommand:"test",language:"en-US",setupItemId:"3208409930553392"},]},],items:[{id:"3195595211854821",name:"Message in subfolder",folderId:"3195588620182363",updated:"2022-05-19T12:05:39.503Z",frontendFolderId:null,text:"Message in subfolder",keywords:"test",subject:"Message in subfolder",slashCommand:"sub",language:"bn-BD",setupItemId:"3195595211854821"},]},],items:[]},],items:[{id:"2888102250465731",name:"bye",folderId:null,updated:"2022-05-25T11:15:36.367Z",frontendFolderId:null,text:"Thanks for contacting us. Please do not hesitate to contact us again if we can be of further assistance.",keywords:"bye",subject:null,slashCommand:null,language:null,setupItemId:"2888102250465731"},]};
result = [];
function iterate(obj) {
(obj.items || []).forEach(function(item) {
result.push(item.id)
});
(obj.folders || []).forEach(function(item) {
iterate(item)
});
}
iterate(obj);
console.log(result)

const data = {
id: "0",
name: null,
parentId: null,
folderType: "chatCannedMessages",
folders: [{
id: 3195588631115178,
name: "Testfolder",
parentId: null,
folderType: "chatCannedMessages",
folders: [{
id: "3195588620182363",
name: "Subfolder",
parentId: "3195588631115178",
folderType: "chatCannedMessages",
folders: [{
id: "3206824598737435",
name: "Interesting",
parentId: "3195588620182363",
folderType: "chatCannedMessages",
folders: [],
items: [{
id: "3208409930553392",
name: "Canned Message",
folderId: "3206824598737435",
updated: "2022-05-27T07:28:40.450Z",
frontendFolderId: null,
text: "<p>This is an HTML with Image.</p>",
keywords: "test",
subject: "What kind of subject",
slashCommand: "test",
language: "en-US",
setupItemId: "3208409930553392",
}, ],
}, ],
items: [{
id: "3195595211854821",
name: "Message in subfolder",
folderId: "3195588620182363",
updated: "2022-05-19T12:05:39.503Z",
frontendFolderId: null,
text: "Message in subfolder",
keywords: "test",
subject: "Message in subfolder",
slashCommand: "sub",
language: "bn-BD",
setupItemId: "3195595211854821",
}, ],
}, ],
items: [],
}, ],
items: [{
id: "2888102250465731",
name: "bye",
folderId: null,
updated: "2022-05-25T11:15:36.367Z",
frontendFolderId: null,
text: "Thanks for contacting us. Please do not hesitate to contact us again if we can be of further assistance.",
keywords: "bye",
subject: null,
slashCommand: null,
language: null,
setupItemId: "2888102250465731",
}, ],
};
const ids = []
function traverse(obj, parent) {
if (obj === null) return
if (Array.isArray(obj)) {
for (const item of obj) {
traverse(item, parent)
}
} else if (typeof obj === 'object') {
if (parent === 'items') {
ids.push(obj.id)
} else {
for (const [key, value] of Object.entries(obj)) {
traverse(value, key)
}
}
}
}
traverse(data, '')
console.log(ids)

You can solve your problem by applying a recursive logic. The pattern is that if the last descendant object was items, then any direct object descendants (with possible arrays in-between of the hierarchy) are having ids that we need to collect
let input = {
items: [
{
id: 1,
foo: [
{
id: 2,
items: [
{
id: 3,
items: [
{
bar: [
{
id: 4
}
]
},
{
id: 5
}
]
}
]
}
]
}
]
}
let ids = [];
function getItemIDs(obj, wasItems = false) {
if (Array.isArray(obj) || (typeof obj === "object")) {
if (wasItems && (!Array.isArray(obj))) {
ids.push(obj.id);
}
for (let key in obj) {
if (Array.isArray(obj[key]) || (typeof obj[key] === "object")) {
getItemIDs(obj[key], (key === "items") || (wasItems && !Array.isArray(obj[key])))
}
}
}
}
getItemIDs(input);
console.log(ids);

Related

Convert nested JSON Object into a specific array format

I have nested JSON object looking like below and this JSON object I have to convert into some particular format which I have given below:
let jsonObj ={"data": {
"cardShop": {
"cardData": {
"cardTitle": "The Platinum Card<sup>®</sup>",
"cardType": "credit-cards",
"dtmProductName": "PlatinumCard",
"viewAllCards": {
"url": "credit-cards/all-cards",
"text": "All Cards"
}
},
"eligibilityChecker": {
"header": "Check your eligibility",
"subHeader": "The Platinum Card®",
"bulletPoints": [
"Only takes a couple of minutes to complete",
"Will not impact your credit rating",
"Allows you to apply with confidence"
]
}
}
}
}
And the above JSON object I have to convert it to the below format with some new properties like key, title, parentId, id, etc..
[
{
id: "cardShop",
key: "cardShop",
title: "cardShop",
selectable: false,
children: [
{
id: "cardData",
path:"cardShopCardData"
key: "cardData",
title: "cardData",
parentId: "cardShop",
selectable: false,
children: [
{
id: "cardTitle",
path :"cardShopcardDatacardTitle"
key: "cardTitle",
title: "cardTitle",
parentId: "cardData",
isLeaf: true,
children: []
},
{
id: "cardType",
key: "cardType",
title: "cardType",
parentId: "cardData",
isLeaf: true,
children: []
},
{
id: "dtmProductName",
key: "dtmProductName",
title: "dtmProductName",
parentId: "cardData",
isLeaf: true,
children: []
},
{
id: "viewAllCards",
key: "viewAllCards",
title: "viewAllCards",
parentId: "cardData",
selectable: false,
children: [
{
id: "url",
key: "url",
title: "url",
parentId: "viewAllCards",
isLeaf: true,
},
{
id: "text",
key: "text",
title: "text",
parentId: "viewAllCards",
isLeaf: true,
}
]
}
]
},
{
id: "eligibilityChecker",
key: "eligibilityChecker",
title: "eligibilityChecker",
parentId: "cardData",
selectable: false,
children: [
{
id: "header",
key: "header",
title: "header",
parentId: "eligibilityChecker",
},
{
id: "subHeader",
key: "subHeader",
title: "subHeader",
parentId: "eligibilityChecker",
},
{
id: "bulletPoints",
key: "bulletPoints",
title: "bulletPoints",
parentId: "eligibilityChecker",
},
{
id: "image",
key: "image",
title: "image",
parentId: "eligibilityChecker",
}
]
}
]
}
];
I have tried below things. For each object I need a parentId.
let prevKey =""
const iterate = (obj) => {
Object.keys(obj).forEach(key => {
if (typeof obj[key] === 'object' && obj[key] !== null) {
let c ={
id:key,
title:key,
selelected:false,
children:[]
};
if(prevKey && Object.keys(output).length === 0){
output ={
children :[]
}
output.children.push(c)
}
else if(prevKey ){
output.children.push(c)
} else{
output = c
}
prevKey = key;
iterate(obj[key])
}
else{
let c ={
id:key,
title:key,
selelected:false,
children:[]
};
output.children[0].children.push(c)
}
})
}
I have tried using recursion but somehow I am not able to get an expected output.
you can do something like this
const transform = data => {
const loop = (data, parent) => Object.entries(data).map(([key, value]) => {
let additional = parent? {
parentId: parent
}:{}
if(typeof value === 'object' && !Array.isArray(value)){
additional = {
...additional,
selectable: false,
children: loop(value, key)
}
}else{
additional.isLeaf = true
}
return {
id: key,
key,
title: key,
...additional
}
})
return loop(data)
}
let jsonObj = {
"data": {
"cardShop": {
"cardData": {
"cardTitle": "The Platinum Card<sup>®</sup>",
"cardType": "credit-cards",
"dtmProductName": "PlatinumCard",
"viewAllCards": {
"url": "credit-cards/all-cards",
"text": "All Cards"
}
},
"eligibilityChecker": {
"header": "Check your eligibility",
"subHeader": "The Platinum Card®",
"bulletPoints": [
"Only takes a couple of minutes to complete",
"Will not impact your credit rating",
"Allows you to apply with confidence"
]
}
}
}
}
console.log(transform(jsonObj.data))

How to populate a flat array in javascript

My goal is to create a tree-like structure that automatically orders the following data.
The subSkills property contains a list of id references to other skills.
[
{
name: "chess";
subSkills: [];
parentId: "games";
_id: "chess";
},
{
name: "games";
subSkills: ["chess",...];
parentId: "";
_id: "games";
},
]
export default interface ISkill {
name: string;
subSkills: string[] | ISkill[];
parentId: string;
_id: string;
}
The result should be something like this.
[
{
name: "games";
subSkills: [
{
name: "chess";
subSkills: [{}...];
parentId: "games";
_id: "chess";
}
];
parentId: "";
_id: "games";
}, ... {}
]
I should note that the function has to be able to handle any level of depth. As I have no experience with
stuff like this, I would appreciate it if anyone could describe their way of thinking.
Thanks in advance.
EDIT: I have multiple trees/roots in the database. So multiple skills have a "" as parentId.
Based to my understanding, each object of the given array will be either a root or a child of another root object. I don't know if you mistakenly filled the subSkills array of an object or is it something to be considered so should be replaced with the whole object if found? per my assumption I just don't have subSkills as strings for now, I set all subSkills to empty array to start with, let me know if this something that should be considered please. otherwise you can actually just see if the string is met then you can remove it from the array and replace it with the child object itself.
Here's my solution:
const givenArray = [
{
name: "chess",
subSkills: [],
parentId: "games",
_id: "chess",
},
{
name: "games",
subSkills: [],
parentId: "",
_id: "games",
},
{
name: "programming dev",
subSkills: [],
parentId: "chess",
_id: "programming",
},
{
name: "basketball 01",
subSkills: [],
parentId: "chess",
_id: "basketball",
},
];
const skillsAggregator = (skills) => {
const newSkills = [...skills];
newSkills.forEach((skill) => {
if (!!skill.parentId.length) {
addSubSkills(newSkills, skill);
}
});
return newSkills;
};
const addSubSkills = (skills, currentSkill) => {
for (let i = 0; i < skills.length; i++) {
const skill = skills[i];
if (currentSkill.parentId === skill._id) {
skill.subSkills.push(currentSkill);
break;
}
}
};
console.log(JSON.stringify(skillsAggregator(givenArray), null, 2));
NOTE
If you can update your data structure (and you can) to a Map or a literal object, the algorithm will be faster than with array, here's an example with extra deep nesting level:
const givenArray = {
chess: {
name: "chess",
subSkills: [],
parentId: "games",
_id: "chess",
},
games: {
name: "games",
subSkills: [],
parentId: "",
_id: "games",
},
programming: {
name: "programming dev",
subSkills: [],
parentId: "chess",
_id: "programming",
},
basketball: {
name: "basketball 01",
subSkills: [],
parentId: "chess",
_id: "basketball",
},
football: {
name: "football",
subSkills: [],
parentId: "basketball",
_id: "football",
},
};
const skillsAggregator = (skills) => {
const newSkills = { ...skills };
Object.entries(newSkills).forEach(([id, skill]) => {
if (!!skill.parentId.length) {
newSkills[skill.parentId].subSkills.push(skill);
}
});
return newSkills;
};
console.log(JSON.stringify(skillsAggregator(givenArray), null, 2));

How to sort nested array object using another nested array of on the basis of id?

My objective here is to convert the input array into the structure of the output array.
The input array and output array are shown below. If you observe carefully we can see that id is common in both the arrays and only title changes.
var output = [{
id: "1",
title: 'title',
children: [],
},
{
id: "2",
title: 'title2',
children: [],
},
{
id: "3",
title: 'title3',
children: [{
id: "4",
title: 'title4',
children: [],
}, {
id: "5",
title: 'title5',
children: [{
id: "6",
title: 'title6',
children: [],
}, {
id: "7",
title: 'title7',
children: [],
}, {
id: "9",
title: 'title9',
children: [],
}]
}],
}
]
var input = [{
id: "1",
title: 'title_chnaged',
children: [],
},
{
id: "2",
title: 'title_changed',
children: []
},
{
id: "3",
title: 'title_changed',
children: [{
id: "4",
title: 'title_changed',
children: [],
}, {
id: "5",
title: 'title_changed',
children: [],
children: [{
id: "6",
title: 'title_changed',
children: [],
},
{
id: "7",
title: 'title_changed',
children: [],
}
]
}],
},
{
id: "9",
title: 'title_chnaged',
children: [],
}
]
This function will look into the input array of corresponding element of output array on the . basis of id
let found;
function findTheKey(id, widget) {
let newObj = [...widget];
for (var key in newObj) {
if (newObj[key]["id"] == id) {
found = newObj[key];
break;
}
if (newObj[key].hasOwnProperty("children")) {
findTheKey(id, newObj[key].children);
}
}
return found;
}
This function will iterate over the output array and look for corresponding element in input array
function findAllObjectOnArray(output) {
let newObj = [...output];
for (let key in newObj) {
newObj[key] = {
...findTheKey(newObj[key]['id'], input),
children: newObj[key].children
};
if (newObj[key].hasOwnProperty("children")) {
findAllObjectOnArray(newObj[key].children, input);
}
}
return newObj;
}
var result = findAllObjectOnArray(output)
console.log(result)
The result is as expected on label 1 but as we move into nested object, it didn't changed.
Please suggest me something which will let it work. Any hint or solution is highly welcome ?
I've created a function fn that maps array elements to elemnts with property title = "title"+id and then recursively maps children nodes.
var output = [
{
id: "1",
title: 'title',
children: [],
},
{
id: "2",
title: 'title2',
children: [],
},
{
id: "3",
title: 'title3',
children: [
{
id: "4",
title: 'title4',
children: [],
},
{
id: "5",
title: 'title5',
children: [
{
id: "6",
title: 'title6',
children: [],
},
{
id: "7",
title: 'title7',
children: [],
},
{
id: "9",
title: 'title9',
children: [],
}]
}],
}]
var input = [
{
id: "1",
title: 'title_chnaged',
children: [],
},
{
id: "2",
title: 'title_changed',
children: []
},
{
id: "3",
title: 'title_changed',
children: [
{
id: "4",
title: 'title_changed',
children: [],
},
{
id: "5",
title: 'title_changed',
children: [],
children: [
{
id: "6",
title: 'title_changed',
children: [],
},
{
id: "7",
title: 'title_changed',
children: [],
}]
}],
},
{
id: "9",
title: 'title_chnaged',
children: [],
}]
var fn = node =>
node && node.map( x =>
({
...x,
title: "title"+x.id,
children: fn(x.children)
})
)
var result = fn(output)
console.log(result)
A tip: Either stick to immutable (copy all objects) or modify it in-place. Things become really complicated when you mix the two unless you know what you are doing.
I'm not entirely sure if this is what you mean? It's hard to be sure if it works correctly because the title_changed strings are all the same.
I just added newObj[key].children = findAllObjectOnArray(newObj[key].children); so that the children property gets updated correctly (since you make a clone of the array on every call, so children doesn't get updated when you try to modify it by reference).
var output = [
{
id: "1",
title: 'title',
children: [],
},
{
id: "2",
title: 'title2',
children: [],
},
{
id: "3",
title: 'title3',
children: [
{
id: "4",
title: 'title4',
children: [],
},
{
id: "5",
title: 'title5',
children: [
{
id: "6",
title: 'title6',
children: [],
},
{
id: "7",
title: 'title7',
children: [],
},
{
id: "9",
title: 'title9',
children: [],
}]
}],
}]
var input = [
{
id: "1",
title: 'title_chnaged',
children: [],
},
{
id: "2",
title: 'title_changed',
children: []
},
{
id: "3",
title: 'title_changed',
children: [
{
id: "4",
title: 'title_changed',
children: [],
},
{
id: "5",
title: 'title_changed',
children: [],
children: [
{
id: "6",
title: 'title_changed',
children: [],
},
{
id: "7",
title: 'title_changed',
children: [],
}]
}],
},
{
id: "9",
title: 'title_chnaged',
children: [],
}]
let found;
function findTheKey(id, widget) {
let newObj = [...widget];
for (var key in newObj) {
if (newObj[key]["id"] == id) {
found = newObj[key];
break;
}
if (newObj[key].hasOwnProperty("children")) {
findTheKey(id, newObj[key].children);
}
}
return found;
}
function findAllObjectOnArray(output) {
let newObj = [...output];
for (let key in newObj) {
newObj[key] = {
...findTheKey(newObj[key]['id'], input),
children: newObj[key].children
};
if (newObj[key].hasOwnProperty("children")) {
newObj[key].children = findAllObjectOnArray(newObj[key].children);
}
}
return newObj;
}
var result = findAllObjectOnArray(output)
console.log(result)

Why code after return statement executing inside for-in loop in javascript?

my variable look like this
var widgets2 = [{
id: "1",
title: 'title',
children: [],
},
{
id: "2",
title: 'title2',
children: []
},
{
id: "3",
title: 'title3',
children: [{
id: "4",
title: 'title4',
children: [],
}, {
id: "5",
title: 'title5',
children: [],
children: [{
id: "6",
title: 'title6',
children: [],
},
{
id: "7",
title: 'title7',
children: [],
}
]
}],
},
{
id: "9",
title: 'title9',
children: [],
}
]
The function code look like this
function findTheKey(id,widget){
let newObj=[...widget];
for(var key in newObj){
if(newObj[key]['id']==id){
console.log(newObj[key])
return newObj[key];
}
console.log("came here")
if(newObj[key].hasOwnProperty("children")){
findTheKey(id,newObj[key].children);
}
}
}
When the called the function using following code
var result=findTheKey(4,widgets2);
console.log(result)
The result look like this
{id: "4", title: "title4", children: Array(0)}
came here
That means even after executing return statement, console.log getting executed, any help will be highly appreciated.
Thankyou
Since this is a recursive function, the return does not have the effect you expect, you need a variable outside the recursive function to keep the current state of what you want to find.
See the snippet below for example:
var widgets2 = [
{
id: "1",
title: "title",
children: [],
},
{
id: "2",
title: "title2",
children: [],
},
{
id: "3",
title: "title3",
children: [
{
id: "4",
title: "title4",
children: [],
},
{
id: "5",
title: "title5",
children: [],
children: [
{
id: "6",
title: "title6",
children: [],
},
{
id: "7",
title: "title7",
children: [],
},
],
},
],
},
{
id: "9",
title: "title9",
children: [],
},
];
let found;
function findTheKey(id, widget) {
let newObj = [...widget];
for (var key in newObj) {
if (newObj[key]["id"] == id) {
found = newObj[key];
break;
}
if (newObj[key].hasOwnProperty("children")) {
findTheKey(id, newObj[key].children);
}
}
return found;
}
var result = findTheKey(4, widgets2);
console.log(result);
You should update your question for this, but since you asked for it in the comments, here is what I propose.
function findTheKey(id, widget) {
const newObj = [...widget];
for (const key in newObj) {
if (newObj[key]["id"] === `${id}`) {
return newObj[key];
}
if (newObj[key].hasOwnProperty('children')) {
/* Use the result of the recursive function */
const foundObject = findTheKey(id, newObj[key].children);
if(foundObject) return foundObject;
}
}
return false;
}

Efficiently loop through an object based on an array of ids

I am getting the users navigation "state" in a mobile navigation as an Array. For example:
['3124', '5312', '5232']
I need to use that state, to grab the Object that has the ID of '5232', 3 levels down in the object.
The Array length can differ, meaning it can return between 1 and 5 ids, so I don't always have to loop all the way down.
This is what the data for the navigation can look like, using the same IDs as I used in the example above, I would like my function to return the "evening" object with ID '5232':
[
{
id: "3124",
name: "women",
children: [
{
id: "5312",
name: "dresses",
children: [
{
id: "8399",
name: "wedding",
children: []
},
{
id: "5232",
name: "evening",
children: []
}
]
},
{
id: "3291",
name: "shoes",
children: []
}
]
},
{
id: "9482",
name: "men",
children: [
{
id: "8292",
name: "jackets",
children: []
},
{
id: "3829",
name: "hats",
children: []
}
]
}
]
I've been talking this through with a couple of colleagues and we can't really figure out a good way to do this efficiently. We cannot change the data, but we can probably change how the user state is saved, if that is wrong.
I could really use some input and ideas on how to solve this problem in a good way.
Simple function to find node by path in tree
function findNodeByPath(nodes, path) {
let node;
if (!path) return;
for (let id of path) {
if (!nodes) break;
for (let child of nodes) {
if (child.id === id) {
node = child;
nodes = node.children;
break;
}
}
}
return node;
}
let nodes = [
{
id: "3124",
name: "women",
children: [
{
id: "5312",
name: "dresses",
children: [
{
id: "8399",
name: "wedding",
children: []
},
{
id: "5232",
name: "evening",
children: []
}
]
},
{
id: "3291",
name: "shoes",
children: []
}
]
},
{
id: "9482",
name: "men",
children: [
{
id: "8292",
name: "jackets",
children: []
},
{
id: "3829",
name: "hats",
children: []
}
]
}
];
console.log(findNodeByPath(nodes, ['3124', '5312', '5232']));
You could iterate the arrays and take only the node of the given path id.
function getObject(tree, path) {
var temp = { children: tree };
return path.every(p => temp = temp.children.find(({ id }) => p === id))
? temp
: undefined;
}
var data = [{ id: "3124", name: "women", children: [{ id: "5312", name: "dresses", children: [{ id: "8399", name: "wedding", children: [] }, { id: "5232", name: "evening", children: [] }] }, { id: "3291", name: "shoes", children: [] }] }, { id: "9482", name: "men", children: [{ id: "8292", name: "jackets", children: [] }, { id: "3829", name: "hats", children: [] }] }],
path = ['3124', '5312', '5232'],
result = getObject(data, path);
console.log(result);
You can try implementing a basic nested for loop if focusing solely on efficiency. I chose the variable name breadcrumb since the concept seems similar to its role in site navigation.
function getState(breadcrumb, state) {
let states = state;
for (let id of breadcrumb) {
for (state of states) {
// found -- continue to next level
if (state.id === id) {
states = state.children;
break;
}
}
// not found
if (state.id !== id) {
return null;
}
}
return state;
}
let state = [{ id: "3124", name: "women", children: [{ id: "5312", name: "dresses", children: [{ id: "8399", name: "wedding", children: [] }, { id: "5232", name: "evening", children: [] }] }, { id: "3291", name: "shoes", children: [] }] }, { id: "9482", name: "men", children: [{ id: "8292", name: "jackets", children: [] }, { id: "3829", name: "hats", children: [] }] }];
let breadcrumb = ['3124', '5312', '5232'];
console.log(getState(breadcrumb, state));
However, if you care more about code maintainability, I recommend a more canonical approach:
function getState(breadcrumb, state) {
return breadcrumb.reduce((state, id) => {
return state !== null
? state.children.find(state => state.id === id)
: state;
}, { children: state });
}
let state = [{ id: "3124", name: "women", children: [{ id: "5312", name: "dresses", children: [{ id: "8399", name: "wedding", children: [] }, { id: "5232", name: "evening", children: [] }] }, { id: "3291", name: "shoes", children: [] }] }, { id: "9482", name: "men", children: [{ id: "8292", name: "jackets", children: [] }, { id: "3829", name: "hats", children: [] }] }];
let breadcrumb = ['3124', '5312', '5232'];
console.log(getState(breadcrumb, state));
try using recursive function
function findById(id) {
var founded = {};
function recurse(data){
for(var i = 0; i < data.length; i++) {
if (data[i].id === id) {
founded = data[i];
} else if (data[i].children && data[i].children.length) {
recurse(data[i].children);
}
}
}
recurse(catalog);
return founded;
};
some demo : Demo

Categories