Searching for a deeply nested JSON property with lodash

I am dealing with a JSON API response that has the following structure:

[
  {
    title: "top1",
    sections: [
      {
        section_title: "section1",
        content: [
          {
            content_title: "title1",
            content_id: "id1"
          },
          {
            content_title: "title2",
            content_id: "id2"
          }
        ]
      },
      {
        section_title: "section2",
        content: [
          {
            content_title: "title3",
            content_id: "id3"
          },
          {
            content_title: "title4",
            content_id: "id4"
          }
        ]
      }
    ]
  }, {
    title: "top2",
    sections: [...]
  },
  ...
]

In addition, I have a small array of content IDs arr2 = ['id2','id3']. My task is to search the API response data to find any content_id that matches an ID in arr2.

Although I have some lodash code in place, I realize that my nested forEach approach may not be the most efficient:

_.forEach(response, function(top) {
  _.forEach(top.sections, function(section) {
    _.forEach(section.content, function(content) {
      _.forEach(arr2, function(id) {
        if(id === content.content_id) {
         // Do stuff
        }
      })
    })
  })
})

Do you have any suggestions on how I could optimize this code?

Answer №1

Upon further reflection, I've found that there isn't a more elegant solution using different lodash functions. It appears that utilizing the forEach method is necessary to set the owned properties for each case. One small optimization could be to avoid lodash altogether and replace the innermost forEach with the vanilla JavaScript forEach Array method, as well as using find for a potential performance boost.

response.forEach((topItem) => {
    topItem.sections.forEach((section) => {
        section.content.forEach((content) => {
            if(arr2.find((item) => { return item === content.content_id; })){
                topItem.owned = true; section.owned = true; content.owned = true;
            }
        });
    });
});

I personally prefer arrow function syntax as well...

Answer №2

You have the ability to create a function that will recursively go through recognized descendant properties.

function deepWalk(collection, childKeys, iteratee) {

  // generating a partial _.each with an iterator that will
  // recursively navigate through properties from the `childKeys` array
  var each = _.partial(_.each, _, function(value, index) {
    // triggering the iteratee callback
    iteratee(value, index);
    // only recursively navigate through properties found in childKeys
    _(value).pick(childKeys).each(each);
  });

  // triggering the iteration
  each(collection);

}

deepWalk(collection, ['sections', 'content'], function(value) {
  if(_.includes(['id2', 'id3'], value.content_id)) {
    // perform any necessary actions here..
    console.log(value);
  }
});

var collection = [
  {
    title: "top1",
    sections: [
      {
        section_title: "section1",
        content: [
          {
            content_title: "title1",
            content_id: "id1"
          },
          {
            content_title: "title2",
            content_id: "id2"
          }
        ]
      },
      {
        section_title: "section2",
        content: [
          {
            content_title: "title3",
            content_id: "id3"
          },
          {
            content_title: "title4",
            content_id: "id4"
          }
        ]
      }
    ]
  }
];

function deepWalk(collection, childKeys, iteratee) {
  
  // generating a partial _.each with an iterator that will
  // recursively traverse properties from the `childKeys` array
  var each = _.partial(_.each, _, function(value, index) {
    // triggering the iteratee callback
    iteratee(value, index);
    // only recursively navigate through properties found in childKeys
    _(value).pick(childKeys).each(each);
  });
  
  // triggering the iteration
  each(collection);
  
}

deepWalk(collection, ['sections', 'content'], function(value) {
  if(_.includes(['id2', 'id3'], value.content_id)) {
    // perform any necessary actions here..
    console.log(value);
  }
});
.as-console-wrapper { min-height: 100%; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

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

Can you send an array of objects as data in an AJAX post request?

My primary objective is to gather the dropdown values from a webpage and then send them to a PHP file for processing. Currently, I am using jQuery to achieve this by creating an overall schedule array and adding each element to it for updating. Here' ...

A helpful guide on using workbox to effectively cache all URLs that follow the /page/id pattern, where id is a

Looking at this code snippet from my nodejs server: router.get('/page/:id', async function (req, res, next) { var id = req.params.id; if ( typeof req.params.id === "number"){id = parseInt(id);} res.render('page.ejs' , { vara:a , va ...

Retrieving data from MySQL and mapping it to a model class in Android Studio

After numerous attempts to add the COUNT rows of a MySQL table to the ModelCLass, I finally found a method that seemed promising. However, I am encountering an error and struggling to identify where I went wrong. Any assistance would be greatly appreciated ...

Issue with Microsoft Azure and AngularJS: Chart not rendering data as expected

I've encountered an issue where I can view the data locally, but once I open the Windows Azure cloud service application, the Json data is no longer being passed into my chart (). The Console displays a message stating "Controller names should start w ...

Tap on the child to reveal their parent

I am working with a family tree that includes dropdown menus containing the names of parents and children. Each child has a link, and when I click on a child's link, I want their father to be displayed in the dropdown menu as the selected option. Can ...

Choosing different elements using identical classes in JQuery

Struggling with a coding problem that seems like it should be an easy fix, but can't quite figure it out. The HTML code I have is as follows: <section class="actualite"> <div class="actualite-text"> <h3 class="title"&g ...

Displaying subtotal in a list using Vue.js and conditional rendering with v-if statement

Seeking guidance on calculating a total for a vue.js list that contains invoice items. To illustrate, let's consider a scenario where a table of invoice items is being rendered. Here is the code snippet: <table> <template v-for="(invoice_ite ...

Handle all link clicks on the webpage

My challenge is that some users are required to utilize a virtual desktop in order to access specific information on my website. However, within the virtual environment, there are links leading to external content that do not function properly. I am seekin ...

Error encountered in the onPostExecute method due to a type mismatch at line 111 in JSON.java, along with a JSONException stating that the input has ended at character 0

Days have passed, and I am still searching for an answer. As a beginner in android development, I am struggling with the error messages org.json.JSONException: End of input at character 0 and org.json.JSON.typeMismatch(JSON.java:111) appearing in my onPost ...

Tips for showcasing the Phaser game screen exclusively within a React route

I am trying to make sure that my game screen only appears on the '/game' route. However, when I initialize it using the method "new Phaser.Game(config)", it ends up displaying on every route including '/home', the default route '/& ...

Loop through a list of items and apply the bootstrap-select plugin to each

In an attempt to incorporate an update button within a loop using bootstrap-selectpicker, I encountered a challenge. Within each iteration of the loop, there is a form containing multiple select elements with selectpicker and a hidden button to save the se ...

Eliminate redundant items from the array

"name": [ { "name": "test1" }, { "name": "test2" }, { "name": "test3" }, { "name": "test1" }, ] Generated by a Node.js script, the structure ab ...

Issues involving Npm and JSON format

As a newcomer to coding, I wanted to recode a program but realized that I need to get the program running first in order to understand it. However, when I run "npm install" in the command prompt, the following message pops up: up to date, audited 364 p ...

What could be causing the malfunction of my Superfish menu in Firefox?

I am currently experimenting with the Superfish jQuery plugin to improve a drop-down menu on my website. Unfortunately, in Firefox browser (v. 21.0), the drop-down menu does not open when hovering over it as expected. However, it works fine in Chrome and O ...

Unraveling the mystery of polymorphic list deserialization in Java with ArangoDB

Currently, I am working with ArangoDB 3.1 alongside the Java Driver 4.1.10. The current version utilizes Velocypack. My goal is to deserialize / unmarshal a list of objects (Item) that contains various subclasses (such as SimpleItem, ComplexItem). Essent ...

Transforming a CSV row into a JSON object using Java

I have a CSV file that looks like this: "name.firstName","name.givenName","name.DisplayName","phone.type","phone.value" "john","maverick","John Maverick","mobile","123-123-123" "jim","lasher","Jim Lasher","mobile","123-123-123" I need to transform the se ...

Issue with Bootstrap4 Carousel not scrolling horizontally

I'm currently working on creating a carousel following the Bootstrap code snippet page. It features three images and is designed to have slide controls that move left and right. The script tags with the necessary scripts are located at the bottom of t ...

Modify the file format depending on the browser being used as Internet Explorer

Currently seeking the most effective method to dynamically alter the file extension of certain images (from .svg to .png) specifically for Internet Explorer users. Uncertain about the optimal approach: consider parsing the HTML code with PHP utilize jQu ...

Simple Method to Retrieve one document from Firebase v9 in a React Application

Is it possible to retrieve a document from Firebasev9 using a slug instead of an id with the useDocument Hook? useDocument Hook import { useEffect, useState } from "react" // firebase import import { doc, onSnapshot } from "firebase/firesto ...

Is there a way to effectively eliminate an array of objects in JavaScript or TypeScript and alter the object structure simultaneously?

I am seeking solutions to restructure an object that has multiple arrays of objects so that I can access the object directly. console.log(value.data.summary[0].data) Instead of accessing arrays in this manner, I want to modify my data structure. Is there ...