Obtain the leaf nodes from a combination of arrays and objects using Lodash

Here is the code structure I want to share with you before explaining my requirements. It displays the input array layout along with the desired outcome:

[
  {
    link: "someurl",
    name: "Foo",
    subCats: [
      {
        link: "anotherurl",
        name: "Bar",
        subCats: [
          {
            link: "anotherurl",
            subCats: [
              {
                link: "onemorekink"
                name: "Prod",
              }
            ]
          }
        ]
      },
      {
        link: "someurll",
        name: "Fuzzy",
        subCats: [
          {
            link: "besturiever",
            name: "SomeName",
            subCats: [
              {
                link: "onemore",
                name: "Aloc",
                subCats: [
                  {
                    link: "anotherlink"
                    name: "Final",
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  }
]

Now, let me describe the expected result:

{
  link: "onemorekink"
  name: "Prod",
},
{
  link: "anotherlink"
  name: "Final",
}

Hopefully, you grasp the concept. Essentially, I aim to extract the final subCats element without any child subCats and add it to the resulting array. I attempted using Lodash for its excellent array and object manipulation capabilities. Thank you in advance for your assistance.

Answer №1

Give this a shot

let result=[]; // store the result here
let extract = data => data.map(item => item.subCats ? extract(item.subCats) : result.push(item));
extract(arrayData);

let arrayData = [
  {
    link: "someurl",
    name: "Foo",
    subCats: [
      {
        link: "anotherurl",
        name: "Bar",
        subCats: [
          {
            link: "anotherurl",
            subCats: [
              {
                link: "onemorelink",
                name: "Prod",
              }
            ]
          }
        ]
      },
      {
        link: "someurll",
        name: "Fuzzy",
        subCats: [
          {
            link: "besturiever",
            name: "SomeName",
            subCats: [
              {
                link: "onemore",
                name: "Aloc",
                subCats: [
                  {
                    link: "anotherlink",
                    name: "Final",
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  }
];

let result=[];
let extract = data => data.map(item => item.subCats ? extract(item.subCats) : result.push(item));
extract(arrayData);

console.log(result);

Answer №2

Creating a function to achieve this task is actually quite simple, and you can do it without using lodash.

function getFinalLeaves(items, property) {
  let results = [];
  items.forEach((item, index) => {
    if (item[property] && item[property].length) {
      results = results.concat(getFinalLeaves(item[property], property));
    } else if (index === items.length - 1) {
      results.push(item);
    }
  })
  return results;
}

const finalResults = getFinalLeaves(data, 'subCategories');

Answer №3

The solution is quite straightforward and does not require the use of lodash. You can achieve recursion with a simple custom function.

function recursiveFunction(data){
        for(let item of data){
            if(item.subCats){
                recursiveFunction(item.subCats);
            } else {
                console.log(item);
            }
        }
    }

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

Guide to dynamically rendering Material-UI dialogs based on certain conditions

Trying to implement a dialog box based on data returned from an Apollo hook, where I need to verify that one value matches an ID. If checker === true, the dialog should open automatically and close when the user clicks the Close button. const DialogComp ...

RequireJS is timing out while loading the runtime configuration

I keep encountering a load timeout error with my run-time configuration, specifically with common.js. Although I have set the waitseconds value to 0 for files loaded from common.js, the loadTimeout issue persists for common.js itself. index.html <scr ...

Storing dates as collection names is not supported in Firestore

I'm currently facing an issue trying to store stock prices in Firestore. I want the structure to resemble something similar to SQL, like this: const d1 = new Date(); const result = d1.getTime(); console.log('Epochtime',result); database.coll ...

What is the best way to conceal the outline in a popup window?

I have successfully implemented a popup/modal window using JavaScript, but now I need to find a way to hide the outline map container. The initialization code for the map is as follows: self.mapDialogOptions = { autoOpen: false, m ...

Efficiently managing modules with requirejs and Backbone.Marionette

After organizing the file structure of my web app, utilizing RequireJs and Backbone.Marionette, it now looks like this: |- main.js |- app.js |- /subapp1 |- subapp1.js |- subapp1.router.js |- /subapp2 |- subapp2.js | ...

Ways to access information from a SQLite database using Angular

I am a beginner in front-end/back-end communication and I need guidance on how to retrieve data from a SQLite db file to populate a page in my Angular project. I have no idea where to begin, so any resources you can recommend would be greatly appreciated. ...

What is the best way to create a delay so that it only appears after 16 seconds have elapsed?

Is there a way to delay the appearance of the sliding box until 16 seconds have passed? <script type="text/javascript"> $(function() { $(window).scroll(function(){ var distanceTop = $('#last').offset().top - $(window).height(); ...

Refresh information in form after submitting with Remix

Currently, I am utilizing the Remix Form element to display my form with various input fields. When there is a server-side validation error, the entered text in the fields remains, as expected. However, upon successful submission of the form, I would like ...

Finding the median value within a collection of objects

I am working with an array of objects containing book details: const booksData = [{"author":"john","readingTime":12123}, {"author":"romero","readingTime":908}, ...

Control Center for JavaScript Administration

When dealing with Javascript content on a larger website, what is the best way to efficiently manage it? I am facing challenges with multiple $(document).ready()'s and the need to handle numerous id strings ($('#id')). One idea was to combin ...

Mirror the content of my div code onto a two-dimensional plane using an A-frame

Query I am currently developing a 3D scene using A-Frame () and I am in need of a solution to mirror an HTML div onto a plane within the A-Frame environment. For instance, imagine a scenario where there is a div at the bottom left corner of the screen fun ...

Error in accessing a null property in JavaScript on a different HTML page

My website consists of multiple HTML pages that are all linked to the same JavaScript file containing several IIFE functions. One of the functions is responsible for controlling a specific button that only appears on one page. However, when accessing other ...

Tips for utilizing the standard search functionality of Select2 while also implementing a remote data source

Even though I am able to populate the dropdown from the data source, there is an issue with filtering the results using the search field at the top. If I make an AJAX request to the API, fetch the data, create <option> elements for each result, and a ...

Using JQuery and JavaScript to store and dynamically apply functions

I have a code snippet that looks like this:. var nextSibling = $(this.parentNode).next(); I am interested in dynamically changing the next() function to prev(), based on a keypress event. (The context here is an input element within a table). Can someo ...

Is there a way to load an image asynchronously when the page loads and show a loading gif during the loading process?

My image tag displays a dynamically generated graph from the database. The loading time can vary significantly, sometimes only taking a second while other times it may take up to 6 or 7 seconds for the graph image to appear. I am looking for a way to sho ...

Verify the length of an array within an object using JavaScript

I am facing a problem with an object. Here is what it looks like: const array = { "entities": [ { "annexes": [ { "buildingUniqueIds": [] }, { ...

Leveraging classes in routing with express framework

After deciding to convert the code from functions to classes, I ran into an issue where 'this' was undefined. Routing // router.js const ExampleController = require('./ExampleController'); const instanceOfExampleController = new Exam ...

Creating a promise to write data to a file

When executing the function, it creates a series of files but fails to write data to them. Strangely, omitting Promise.all at the end and not resolving the function actually results in the data being written to the files. It's puzzling that no matter ...

Error: Unable to access 'push' property of null object in Next.js Link

Utilizing Vite to develop a reusable component has led to an error upon publishing and reusing it: TypeError: Cannot read properties of null (reading 'push') The code for the component is as follows: import React from "react"; import ...

Can you share tips for passing a variable from a post request to a function that accepts parameters as a string or an array of strings in Node.js?

I am struggling to insert the variable named query into the end of the prompt. I attempted to use template literals but it was unsuccessful. (async () => { const gbtResponse = await openai.createCompletion({ model: "text-davinci-002", prompt ...