Retrieve information from arrays within objects in a nested structure

I am working with structured data that looks like the example below:

const arr = [{
    id: 0,
    name: 'Biomes',
    icon: 'mdi-image-filter-hdr',
    isParent: true,
    children: [{
        id: 1,
        name: 'Redwood forest',
        icon: 'mdi-image-filter-hdr'
    }]
},{
    id: 2,
    name: 'Trees',
    icon: 'mdi-pine-tree',
    children: [{
        id: 8,
        name: 'Redwood',
        icon: 'mdi-pine-tree'
    }]
}];

The main array consists of objects, each object having a field children which can also be an array of objects. If I have the value of id, how can I locate the object (especially the object name) based on that id?

Answer №1

const arr = [{
    id: 0,
    name: 'Biomes',
    icon: 'mdi-image-filter-hdr',
    isParent: true,
    children: [{
        id: 1,
        name: 'Redwood forest',
        icon: 'mdi-image-filter-hdr'
    }]
},{
    id: 2,
    name: 'Trees',
    icon: 'mdi-pine-tree',
    children: [{
        id: 0,
        name: 'whatever',
        icon: 'new-tree'
    },{
        id: 8,
        name: 'Redwood',
        icon: 'mdi-pine-tree'
    }]
}];

const findById = (id) => arr
    .filter(x => x.id === id || x.children.some(child => id === child.id))
    .map(y => ({...y, children: y.children.filter(child => id === child.id)}))

console.log(findById(0))

You can initially filter out all parents that have the same id or if the parent has a child with the same id using some. Then, use map and filter to eliminate all children who do not match the id.

Answer №2

You have the option to utilize recursion in this scenario to retrieve the object regardless of how deep it is nested. I have specifically filtered out the object to only display it without the children property. Feel free to include it as needed.

function getObjectFromId(arr, id) {
  for (let i = 0; i < arr.length; ++i) {
    if (arr[i].id === id) {
     // return arr[i]   // If you want full object with children
      const { children, ...rest } = arr[i];
      return rest;
    }
    if (arr[i].children) {
      const result = getObjectFromId(arr[i].children, id);
      if (result) return result;
    }
  }
}

const arr = [
  {
    id: 0,
    name: "Biomes",
    icon: "mdi-image-filter-hdr",
    isParent: true,
    children: [
      {
        id: 1,
        name: "Redwood forest",
        icon: "mdi-image-filter-hdr",
      },
    ],
  },
  {
    id: 2,
    name: "Trees",
    icon: "mdi-pine-tree",
    children: [
      {
        id: 8,
        name: "Redwood",
        icon: "mdi-pine-tree",
        children: [
          {
            id: 9,
            name: "Redwood",
            icon: "mdi-pine-tree",
          },
        ],
      },
    ],
  },
];

function getObjectFromId(arr, id) {
  for (let i = 0; i < arr.length; ++i) {
    if (arr[i].id === id) {
      // return arr[i]   // If you want full object with children
      const { children, ...rest } = arr[i];
      return rest;
    }
    if (arr[i].children) {
      const result = getObjectFromId(arr[i].children, id);
      if (result) return result;
    }
  }
}

console.log(getObjectFromId(arr, 1));
console.log(getObjectFromId(arr, 8));
console.log(getObjectFromId(arr, 9));
/* This is not a part of answer. It is just to give the output fill height. So IGNORE IT */
.as-console-wrapper { max-height: 100% !important; top: 0; }

Answer №3

Method 1: Utilizing two for loops.

const data = [{
    id: 0,
    name: 'Biomes',
    icon: 'mdi-image-filter-hdr',
    isParent: true,
    children: [{
      id: 1,
      name: "Redwood forest",
      icon: 'mdi-image-filter-hdr'
    }]
  },
  {
    id: 2,
    name: 'Trees',
    icon: 'mdi-pine-tree',
    children: [{
      id: 8,
      name: "Redwood",
      icon: 'mdi-pine-tree',
    }]
  }
];

console.log(findById(8));

function findById(id) {
  for (const parent of data) {
    if (parent.id === id)
      return parent;     
    for (const child of parent.children)
      if (child.id === id)
        return child;
  }
  return null;
}

Method 2: Handling multiple nested layers:

const data = [{
    id: 0,
    name: 'Biomes',
    icon: 'mdi-image-filter-hdr',
    isParent: true,
    children: [{
      id: 1,
      name: "Redwood forest",
      icon: 'mdi-image-filter-hdr'
    }]
  },
  {
    id: 2,
    name: 'Trees',
    icon: 'mdi-pine-tree',
    children: [{
      id: 8,
      name: "Redwood",
      icon: 'mdi-pine-tree',
      children: [{
        id: 12,
        name: "Test Level 2",
        icon: 'mdi-pine-tree',
        children: [{
          id: 13,
          name: "Test Level 3",
          icon: 'mdi-pine-tree',
        }]
      }]
    }]
  }
];

console.log(findById(13, data));

function findById(id, array) {
  for (const parent of array) {
    if (parent.id === id)
      return parent;

    if ('children' in parent) {
      const result = findById(id, parent.children);
      if (result) return result;
    }
  }

  return null;
}

Answer №4

Discovering elements at both the parent and child levels

const arr=[{id:0,name:'Biomes',icon:'mdi-image-filter-hdr',isParent:!0,children:[{id:1,name:"Redwood forest",icon:'mdi-image-filter-hdr'}]},{id:2,name:'Trees',icon:'mdi-pine-tree',children:[{id:8,name:"Redwood",icon:'mdi-pine-tree',}]]

const res = arr.reduce((a,item)=>{
    const { children, ...i} = item; 
    a.push(...children, i);
    return a; 
},[]);

function findInData(id){
  return res.find(o=>o.id===id);
}

console.log(findInData(8)?.name);
console.log(findInData(2)?.name);

Answer №5

Initial parameter for child

Secondary parameter for main

const array = [
    {id: 0,name: 'Territories',icon: 'mdi-image-filter-hdr',isParent: true,
    children: [{id: 1,name: 'Redwood forest',icon: 'mdi-image-filter-hdr',},],},
    {id: 2,name: 'Plants',icon: 'mdi-pine-tree',
    children: [{id: 8,name: 'Redwood',icon: 'mdi-pine-tree',},],},
];

const findChildById = (_identifier, _secondaryId = false)=>{
    for(const primary of array){
        if(_secondaryId !== false && primary.id !== _identifier)continue;
        for(const child of primary.children){
            if(child.id === _identifier)return child;
        }
    }
    return false;
};

(async()=>{
    const target_id = 8;

    //

    const result = findChildById(target_id);
    console.log('Located', result);
})();

Answer №6

function searchChild(data, childId) {
  for (let i = 0; i < data.length; i += 1) {
    if (data[i].id === childId) return data[i].name
    let result = data[i].children.find(child => child.id === childId)
    if (result) return result.name
  }

  return null
}


const list = [{
  id: 0,
  name: 'Biomes',
  icon: 'mdi-image-filter-hdr',
  isParent: true,
  children: [{
    id: 1,
    name: 'Redwood forest',
    icon: 'mdi-image-filter-hdr'
  }]
}, {
  id: 2,
  name: 'Trees',
  icon: 'mdi-pine-tree',
  children: [{
    id: 8,
    name: 'Redwood',
    icon: 'mdi-pine-tree'
  }]
}];

console.log(searchChild(list, 2))

Answer №7

To implement this solution, utilize the Array find() method.

Visit this link for more information on Array find()

let result = arr.find((item) => item.id === "your ID");
console.log(result?.name);

const arr = [{
    id: 0,
    name: 'Forests',
    icon: 'mdi-image-filter-hdr',
    isParent: true,
    children: [{
        id: 1,
        name: 'Redwood forest',
        icon: 'mdi-image-filter-hdr'
    }]
},{
    id: 2,
    name: 'Trees',
    icon: 'mdi-pine-tree',
    children: [{
        id: 8,
        name: 'Redwood',
        icon: 'mdi-pine-tree'
    }]
}];

let result = arr.find((item) => item.id === 2);
console.log(result?.name);

let result = arr.find((item) => item.id === "your ID");
console.log(result?.name);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Ensure that the view is only updated once the JSON has been completely received from the AJAX call in AngularJS

Just starting out with angularJS and still in the learning phase. I'm currently working on creating a navbar for the header that will fetch data from an ajax call. The issue I'm facing is that it displays {{obj.pageData}} until the data is fully ...

A method for dividing a string into separate characters and organizing them into an array of JSON objects

I have a collection of JSON objects with a fixed key 'type' and additional keys based on the type. Here is an example of how it looks: theArray = [ { "type": "text", "text": "= SUM(" ...

Maximizing the potential of $urlRouterProvider.otherwise in angular js

I am encountering an issue with redirecting to the login screen when there is no UABGlobalAdminId in my storage. I have tried using $urlRouterProvider.otherwise but it doesn't seem to be functioning properly. When I attempt to debug, the console does ...

I'm experiencing an issue with res.redirect() as it is not directing me to the expected page. Despite no errors being shown, I am left wondering what

Despite everything working as expected, I am facing an issue with redirecting the user to a different URL after they send a message. I have tried using res.redirect from the server side in response to an AJAX POST request, but it seems like I am still on t ...

executing a JavaScript function in a separate .js document

When working with the success callback function in my AJAX post, I encountered an issue trying to call a function from another JavaScript file. Within page1.html: <head> <link href="style.css" rel="stylesheet" type="text/css" /> <s ...

Error: Firebase Error - Unable to find Firebase App 'default'. Please ensure that Firebase App.initializeApp() is called before trying to access the app

Hello, I'm really struggling with this issue - despite reading through multiple posts here, I can't seem to fix this error. Here is the code snippet from my init.js: import firebase from "firebase/app" var config = { apiKey: "A ...

The issue with mapDispathToProps is that it is failing to assign a function

import React, { Component } from "react"; import PropTypes from "prop-types"; import { connect } from "react-redux"; import { ShelfModal } from "./shelf-modal"; import { openShelfModal } from "../../../redux/actions/shelf-modal"; export class ShelfTest ex ...

What is the best way to send the value of this variable through the parameters?

In jQuery: initializeSliders(socket, '!{requestData}'); requestData is a special object (an HTTP request object in my Express.js web application) that contains information such as my session. However, when I pass this object into the initialize ...

Passing data from a Vue.js component to a router in index.js

I am attempting to transmit a JWT token value from the component Login.vue and verify it in the router/index.js before directing the user to the next page. Login.vue: <script> import axios from "axios"; export default { name: "Login", m ...

Using HTML5 Canvas with Firefox 4: How to Retrieve Click Coordinates

Lately, I've been diving into creating HTML5 Video and Canvas demos. Initially, my focus was on optimizing them for Chrome, but now I'm shifting my attention to Firefox and Safari as well. One particular demo I'm currently working on involv ...

I am interested in retrieving a variable from a function

this is some unique HTML code <form id="upload"> <label for="file">Choose a File to Upload</label> <input type="file" id="file" accept=".json"> <butto ...

When the browser's back button is clicked, no action occurs with Next/router

I am confused about why my page does not reload when I use the browser's back button. On my website, I have a catalog component located inside /pages/index.js as the home page. There is also a dynamic route that allows users to navigate to specific p ...

Ways to incorporate react suspense with redux toolkit

I am currently using Redux toolkit to display data from an API, and I want to show the user a "loading data..." message or a spinner before displaying the city information. I have been attempting to use React Suspense, but it doesn't seem to be worki ...

Trouble with formatting in React

I am presented with the following code snippet that I did not author: render: function () { if(this.state.loading){ return <div><span><i className="fa fa-spinner fa-spin"></i> Loading...</span></div& ...

What is the best method for saving Vue's `prototype.$something` in a distinct file?

Is there a way to declare Vue.prototype.$myVariable in a separate file without cluttering the main.js? ...

Could you provide the parameters for the next() function in Express?

Working with Express.js to build an API has been a game-changer for me. I've learned how to utilize middlewares, handle requests and responses, navigate through different middleware functions... But there's one thing that keeps boggling my mind, ...

Tips for deleting multiple uploaded images from an array using Vue.Js and updating the UI accordingly

I am currently utilizing VueJs to upload multiple images. I am saving their respective base64 values in an Array to store them in the database. I have also added a remove feature, so when the user clicks on the remove button, it finds the index of that ele ...

Integrating Whatsapp cloud API with a React web application allows for seamless communication between

I'm currently in the process of integrating my web application with the WhatsApp cloud API. While I've had success sending test messages, I am now looking to incorporate variables as outlined in the API documentation. However, I seem to be encoun ...

Utilizing jQuery ajax to dynamically update map markers on Google Maps at intervals

I am currently working on a project that involves updating a Google map with a marker at regular intervals. I have an Ajax request that retrieves a single latitude and longitude coordinate, but I'm struggling to display it on the map. One option coul ...

What is the best way to implement client side validation for a related input field using JavaScript in a Rails application?

Struggling to find a solution for adding a validation check for a dropdown list that is dependent on another input selection in a different form. It seems like database validation may be necessary, but I'm unsure of the best approach. Any suggestions ...