1

Hello I am trying to figure out how to get the object with a specific id from an array with mutlitple levels. The array will have objects, these objects may have arrays with objects as values. For example see the data given below:

[
 {
 "id": "e1f015d3-4ca8-4dfd-839d-bed9bbbb82f8",
 "text": "Parent Menu 2",
 "icon": "e1f015d3-4ca8-4dfd-839d-bed9bbbb82f8/rose-3142529__340.jpg",
 "page_type": "parent_menu",
 "data": "e1f015d3-4ca8-4dfd-839d-bed9bbbb82f8",
 "ui_config": "",
 "order": 2
 },
 {
 "id": "5bc4ff1a-69b5-496b-a484-0aa99b886122",
 "text": "Home",
 "icon": "5bc4ff1a-69b5-496b-a484-0aa99b886122/1024x1024.png",
 "page_type": "parent_menu",
 "is_homepage": true,
 "data": "5bc4ff1a-69b5-496b-a484-0aa99b886122",
 "ui_config": "",
 "order": 1,
 "submenus": [
 {
 "id": "4960a54c-6d27-4d8d-a272-ebc7d9e8a55e",
 "text": "Grid Menu",
 "icon": "4960a54c-6d27-4d8d-a272-ebc7d9e8a55e/rose-3142529__340.jpg",
 "page_type": "grid_menu",
 "data": "4960a54c-6d27-4d8d-a272-ebc7d9e8a55e",
 "ui_config": "",
 "order": 1,
 "submenus": [
 {
 "id": "906cd86f-df57-4175-a2c6-ca3a5c724e8a",
 "text": "Article Page 2",
 "icon": "906cd86f-df57-4175-a2c6-ca3a5c724e8a/rose-3142529__340.jpg",
 "page_type": "article_page",
 "data": "{\"page_id\":\"3e025c87-1d03-46a6-800e-0a9daea52bf4\"}",
 "ui_config": "",
 "order": 2
 },
 {
 "id": "da8b054a-274e-4e1b-9d5a-e058a934838b",
 "text": "Article Page",
 "icon": "da8b054a-274e-4e1b-9d5a-e058a934838b/rose-3142529__340.jpg",
 "page_type": "article_page",
 "data": "{\"page_id\":\"3e025c87-1d03-46a6-800e-0a9daea52bf4\"}",
 "ui_config": "",
 "order": 1
 }
 ]
 }
 ]
 }
]

Here lets say I need to get the object with id da8b054a-274e-4e1b-9d5a-e058a934838b. How do I do that?

Here is a recurisve function I wrote for this:

var currentMenuItem = null
function getTheCurrentMenu(menu, id) {
 if (currentMenuItem != null) {
 return
 }
 if (!Array.isArray(menu)) {
 if (menu.id == id) {
 currentMenuItem = menu
 return
 }
 }
 for (var item in menu) {
 console.log(item)
 getTheCurrentMenu(item, id)
 }
}

This makes the browser unresponsive and shows error too much recursion.

Can someone please help me with this?

asked May 2, 2019 at 7:35

3 Answers 3

4

You could take an iterative and recursive call with a short circuit, if the item is found.

function find(array, id) {
 var item;
 for (item of array) {
 if (item.id === id) return item;
 if (item.submenus && (item = find(item.submenus, id))) return item;
 }
}
var data = [{ id: "e1f015d3-4ca8-4dfd-839d-bed9bbbb82f8", text: "Parent Menu 2", icon: "e1f015d3-4ca8-4dfd-839d-bed9bbbb82f8/rose-3142529__340.jpg", page_type: "parent_menu", data: "e1f015d3-4ca8-4dfd-839d-bed9bbbb82f8", ui_config: "", order: 2 }, { id: "5bc4ff1a-69b5-496b-a484-0aa99b886122", text: "Home", icon: "5bc4ff1a-69b5-496b-a484-0aa99b886122/1024x1024.png", page_type: "parent_menu", is_homepage: true, data: "5bc4ff1a-69b5-496b-a484-0aa99b886122", ui_config: "", order: 1, submenus: [{ id: "4960a54c-6d27-4d8d-a272-ebc7d9e8a55e", text: "Grid Menu", icon: "4960a54c-6d27-4d8d-a272-ebc7d9e8a55e/rose-3142529__340.jpg", page_type: "grid_menu", data: "4960a54c-6d27-4d8d-a272-ebc7d9e8a55e", ui_config: "", order: 1, submenus: [{ id: "906cd86f-df57-4175-a2c6-ca3a5c724e8a", text: "Article Page 2", icon: "906cd86f-df57-4175-a2c6-ca3a5c724e8a/rose-3142529__340.jpg", page_type: "article_page", data: "{\"page_id\":\"3e025c87-1d03-46a6-800e-0a9daea52bf4\"}", ui_config: "", order: 2 }, { id: "da8b054a-274e-4e1b-9d5a-e058a934838b", text: "Article Page", icon: "da8b054a-274e-4e1b-9d5a-e058a934838b/rose-3142529__340.jpg", page_type: "article_page", data: "{\"page_id\":\"3e025c87-1d03-46a6-800e-0a9daea52bf4\"}", ui_config: "", order: 1 }] }] }],
 id = 'da8b054a-274e-4e1b-9d5a-e058a934838b',
 result = find(data, id);
console.log(result);

answered May 2, 2019 at 7:41
Sign up to request clarification or add additional context in comments.

6 Comments

Using [].some with side effect is bad practice. Using a for..of loop here is much more idiomatic.
@MadaraUchiha, is it better now?
@NinaScholz will this work, if it has say like 5 levels deep submenus?
@defiant, it should. please try it with your data.
It didn't work with my data. The other answer did. Don't know why it didn even though it works here.
|
3

You can do this using reduce method and set accumulator to current element if id matches.

const data = [{"id":"e1f015d3-4ca8-4dfd-839d-bed9bbbb82f8","text":"Parent Menu 2","icon":"e1f015d3-4ca8-4dfd-839d-bed9bbbb82f8/rose-3142529__340.jpg","page_type":"parent_menu","data":"e1f015d3-4ca8-4dfd-839d-bed9bbbb82f8","ui_config":"","order":2},{"id":"5bc4ff1a-69b5-496b-a484-0aa99b886122","text":"Home","icon":"5bc4ff1a-69b5-496b-a484-0aa99b886122/1024x1024.png","page_type":"parent_menu","is_homepage":true,"data":"5bc4ff1a-69b5-496b-a484-0aa99b886122","ui_config":"","order":1,"submenus":[{"id":"4960a54c-6d27-4d8d-a272-ebc7d9e8a55e","text":"Grid Menu","icon":"4960a54c-6d27-4d8d-a272-ebc7d9e8a55e/rose-3142529__340.jpg","page_type":"grid_menu","data":"4960a54c-6d27-4d8d-a272-ebc7d9e8a55e","ui_config":"","order":1,"submenus":[{"id":"906cd86f-df57-4175-a2c6-ca3a5c724e8a","text":"Article Page 2","icon":"906cd86f-df57-4175-a2c6-ca3a5c724e8a/rose-3142529__340.jpg","page_type":"article_page","data":"{\"page_id\":\"3e025c87-1d03-46a6-800e-0a9daea52bf4\"}","ui_config":"","order":2},{"id":"da8b054a-274e-4e1b-9d5a-e058a934838b","text":"Article Page","icon":"da8b054a-274e-4e1b-9d5a-e058a934838b/rose-3142529__340.jpg","page_type":"article_page","data":"{\"page_id\":\"3e025c87-1d03-46a6-800e-0a9daea52bf4\"}","ui_config":"","order":1}]}]}]
function get(data, id) {
 return data.reduce((r, e) => {
 if(e.id === id) r = e;
 if(!r && e.submenus) return get(e.submenus, id)
 return r;
 }, null)
}
const result = get(data, 'da8b054a-274e-4e1b-9d5a-e058a934838b');
console.log(result)

answered May 2, 2019 at 7:48

Comments

0

var data = `
[
 {
 "id": "e1f015d3-4ca8-4dfd-839d-bed9bbbb82f8",
 "text": "Parent Menu 2",
 "icon": "e1f015d3-4ca8-4dfd-839d-bed9bbbb82f8/rose-3142529__340.jpg",
 "page_type": "parent_menu",
 "data": "e1f015d3-4ca8-4dfd-839d-bed9bbbb82f8",
 "ui_config": "",
 "order": 2
 },
 {
 "id": "5bc4ff1a-69b5-496b-a484-0aa99b886122",
 "text": "Home",
 "icon": "5bc4ff1a-69b5-496b-a484-0aa99b886122/1024x1024.png",
 "page_type": "parent_menu",
 "is_homepage": true,
 "data": "5bc4ff1a-69b5-496b-a484-0aa99b886122",
 "ui_config": "",
 "order": 1,
 "submenus": [
 {
 "id": "4960a54c-6d27-4d8d-a272-ebc7d9e8a55e",
 "text": "Grid Menu",
 "icon": "4960a54c-6d27-4d8d-a272-ebc7d9e8a55e/rose-3142529__340.jpg",
 "page_type": "grid_menu",
 "data": "4960a54c-6d27-4d8d-a272-ebc7d9e8a55e",
 "ui_config": "",
 "order": 1,
 "submenus": [
 {
 "id": "906cd86f-df57-4175-a2c6-ca3a5c724e8a",
 "text": "Article Page 2",
 "icon": "906cd86f-df57-4175-a2c6-ca3a5c724e8a/rose-3142529__340.jpg",
 "page_type": "article_page",
 "ui_config": "",
 "order": 2
 },
 {
 "id": "da8b054a-274e-4e1b-9d5a-e058a934838b",
 "text": "Article Page",
 "icon": "da8b054a-274e-4e1b-9d5a-e058a934838b/rose-3142529__340.jpg",
 "page_type": "article_page",
 "ui_config": "",
 "order": 1
 }
 ]
 }
 ]
 }
]`;
var menu = JSON.parse(data);
async function getTheCurrentMenu(menu, id) {
 if (!Array.isArray(menu)) {
 if (menu.id == id) {
 return menu;
 } else if(menu.submenus){
 return getTheCurrentMenu(menu.submenus, id);
 } else {
 return;
 }
 }
 for (let item of menu) {
 console.log(item)
 let result = await getTheCurrentMenu(item, id);
 if(result != null) {
 return result;
 }
 }
}
getTheCurrentMenu(menu, 'da8b054a-274e-4e1b-9d5a-e058a934838b').then((item) => {
 console.log("Result: ", item);
})

answered May 2, 2019 at 7:53

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.