Inspect the key within a complex hierarchy of nested objects in an array

I am working with an array of nested objects and need to extract the value of a specific key property. Currently, I am using a for loop and checking for the existence of children property, but I feel there might be a more optimal way to accomplish this task. Below is the array of object data that I am working with, where I need to retrieve the text for the id 121.

var abc = [
  {
    id: 1,
    text: 'One',
    children: [
      {id: 11, text: 'One One'},
      {id: 12, text: 'One two', 
       children: [ {id: 121, text: 'one two one'} ]}
    ]
  },
  {
    id: 2,
    text: 'two'
  }
];

The approach I have implemented seems to be very specific to this particular problem. Here is my current code snippet:

for(var val of abc){

  if(val.id == 121){
    console.log('in first loop',val.text);
    break;
  }

  if(Array.isArray(val.children)){

   for(var childVal of val.children) {
       if(childVal.id == 121){
        console.log('in first child', childVal.text); 
         break;
       }
     if(Array.isArray(childVal.children)){
       for(var nextChild of childVal.children){
         if(nextChild.id == 121){
           console.log('in next child', nextChild.text); 
           break;
         }

       }

       }
   }

  }

}

Answer №1

To retrieve the text property of a matched object, you can utilize a recursive function that utilizes a for...in loop.

var data = [{"id":1,"text":"One","children":[{"id":11,"text":"One One"},{"id":12,"text":"One two","children":[{"id":121,"text":"one two one"}]}]},{"id":2,"text":"two"}]

function getProperty(data, key, value) {
  let result = null;

  for (let i in data) {
    if (typeof data[i] == 'object' && !result) {
      result = getProperty(data[i], key, value);
    }

    if (i == key && data[i] == value) {
      result = data;
    }
  }

  return result;
}

const matchedObject = getProperty(data, 'id', 121);
console.log(matchedObject);

Answer №2

If you're looking for a quick solution, you might consider using a short circuit to retrieve the desired property value.

const
    getProperty = (object, key, id) => {
        const findProperty = obj => {
            if (!obj || typeof obj !== 'object') return;
            if (obj.id === id) return { value: obj[key] };
            let value;
            Object.values(obj).some(prop => value = findProperty(prop));
            return value;
        };
        return findProperty(object)?.value;
    };

var items = [{ id: 1, name: 'Item' }, { id: 2, name: 'Another Item', children: [{ id: 21, name: 'Child Item' }] }];

console.log(getProperty(items, 'name', 21));
console.log(getProperty(items, 'name', 500));

Answer №3

Given a scenario where your Elements contain nested Properties within a children attribute, utilizing recursion along with Array.prototype.find() is the optimal approach to locate a specific Element based on its ID:

const findElementById = (arr, id, childProp = 'children', result) => {
  const search = arr => arr.find(obj => obj.id == id && (result = obj) || childProp in obj && search(obj[childProp]));
  return search(arr) && result;
};

const data = [{id: 1, name: 'Item One', children: [{id: 11, name: 'Child One'}, {id: 12, name: 'Child Two', children: [{id: 121, name: 'Grand Child One'}]}]}, {id: 2, name: 'Item Two' }];
console.log( findElementById(data, 121)?.name ); // Grand Child One

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

Learn the technique of looping through multiple HTML elements and wrapping them in Vue.js easily!

i need to wrap 2 HTML elements together Here is my code snippet using Vue.js <tr> <th v-for="(item9,index) in product_all" :key="item9.id"><center>Qty</center></th> <th v-for="(item99,index) in product_all" :key=" ...

What is the best way to target all elements sharing a common class?

Currently, I have a Boolean variable stored in a hidden input field. When the user is signed in, it's set to false; otherwise, it's set to true. I have download buttons that should link to a file for download. My goal is to hide these buttons an ...

Nested asynchronous mapping in Node.js involving multiple HTTP requests

Currently, I am attempting to iterate through an array of URLs and retrieve responses from a specific set of URLs. The goal is for the outer loop to only proceed after all inner requests have been completed, resulting in the desired outcome as shown below: ...

Is there a way to transfer the functionality of openssl_seal from PHP to NodeJS 18?

I'm looking to convert the openssl_seal() function from PHP to NodeJs. The code below is from my PHP SDK and works flawlessly, which is what I want to migrate: $ivLength = openssl_cipher_iv_length('AES-256-CBC') ?: 16; $iv = openssl_random ...

Generate an array of JavaScript objects by converting a batch of JSON objects into objects within a Node.js environment

I am working with a prototype class: function customClass(){ this.a=77; } customClass.prototype.getValue = function(){ console.log(this.a); } and I also have an array of JSON objects: var data=[{a:21},{a:22},{a:23}]; Is there a way to cre ...

Trouble with an external .js script

function displayMessage() { var isConfirmed = confirm("Do you want to proceed?"); if (isConfirmed) { window.location = "./proceed"; } }; function checkIfEmpty(){ console.log("checkIfEmpty"); }; @CHARSET "ISO-8859-1"; form { margin:0 auto; width:300px ...

The functionality of sending a response to a client in Node.js Express seems to be malfunctioning

I am facing an issue with sending a response back to the client. Despite not receiving any errors, it seems like the response is not working as expected. Can anyone help me figure out why? Below is my code snippet: exports.login = function (req, res, next ...

Display HTML code within a data attribute

I have a function that modifies an element from OpenLayers. In the official documentation, it mentions that the property label accepts either HTML or a string. methods: { onUpdatePosition (coordinate) { this.deviceCoordinate = coordinat ...

Embed a partial view within a Jquery modal dialogue box featuring two distinct models

I am working on a room-booking project. In my View, I have a model of rooms that displays the room ID and its characteristics using a foreach loop: @model IEnumerable<Room> <div class="roomConteiner"> @foreach (Room room in Model) ...

Access an HTML file in Text Edit on a Mac directly from a web browser

Is there a way to utilize Javascript or another appropriate script to open an HTML file in Text Edit on my Mac? I have created a local web page using Text Edit that has different tabs linking to other Text Edit files within the page. I am looking for a m ...

Different approaches to transforming jQuery code into functional AngularJS code

I am a beginner in AngularJS and I'm looking to implement functionality for a login page similar to the one you see when you click the 'Forgot Password' link: Would it be more appropriate to use a directive instead of a controller for this ...

Create an instance using the window object in JavaScript

Having an issue when trying to instantiate a class using the window object. I have a namespace called UTIL and within it, there is a class defined as follows: var UTIL = { Classes : {}}; UTIL.Classes.ObservationVal = function(state, id, type, context, pe ...

What are the best practices for implementing jquery owlCarousel within an Angular 4 component?

I've included my 'carousel.js' file like this: $('#owl-carousel-1').owlCarousel({...}); and in carousel.component.html, I have: <div id="owl-carousel-1" class="owl-carousel owl-theme center-owl-nav home- carousel">....< ...

Use Ajax to fetch a nested PHP array in JSON format

Following an Ajax call, I am receiving a multidimensional PHP array named '$tree'. My goal is to convert this array into JSON format. Currently, my PHP page is only outputting the Array: print_r(json_encode($tree)); The success section of my a ...

Having trouble with Angular JS's ngRoute feature not functioning properly

I've been struggling with my ngRoute implementation. I seem to be unable to load the 'ngRoute' module for some reason. Whenever I run this code, I just end up with a blank page. Below is my app.js file: var app = angular.module('tutor ...

Updating item information within an array in Vue.js

I'm currently working on integrating an edit feature into a task application using Vue JS. My issue lies in the fact that I have a click event assigned to the edit button - @click="editShow" which displays input fields for editing all items instead ...

ESLint flags a misuse of promises in my code that I believe is acceptable

This symbol table implementation includes a method that needs some adjustments: public getAllSymbols(type?: typeof Symbol, localOnly = false): Promise<Set<Symbol>> { const promise = super.getAllSymbols(type ?? Symbol, localOnly); ...

Why is it that I am unable to utilize the post data stored in $var within my PHP document when making an Ajax call?

Hey there! I've got this function that makes an ajax call. But, for some reason, the $value I'm passing isn't defined in my showuser.php file. Can you help me figure out why? function showUser2(value) { var xhr = new XMLHttp ...

What is the best way to organize objects based on their timestamps?

I am faced with the task of merging two arrays of objects into a single array based on their timestamps. One array contains exact second timestamps, while the other consists of hourly ranges. My goal is to incorporate the 'humidity' values from t ...

Tips for incorporating jQuery to load Rails form partials and submit them as a single form:

Trying to improve the readability of my Rails HTML code, I decided to extract certain portions into partials and then used jQuery to render these partials. However, a problem arose where the form seems disconnected after implementing this approach. It appe ...