Group of objects containing an inner group of objects

Here is an array of objects that I am working with:

let prova: ActiveRoute[] = [
{
    path: '/Root',
    method: 'GET',
    children: [
        {
            path: '/Son',
            method: 'GET',
            children: [
                {
                    path: '/Grandson',
                    method: 'GET',
                    children: [
                        {
                            path: '/Boh',
                            method: 'GET',
                            activeMessage: 'End',
                        }
                    ],
                }
            ],
        }
    ],
    middleware: [
        'middleware1',
    ],
}

Defined ActiveRoute interface:

export interface  ActiveRoute {
   path: string;
   children?: ActiveRoute[];
   middleware?: string[];
   method?: 'GET' | 'POST' | 'PUT' | 'DELETE';
   activeMessage?: string;

I am attempting to extract and print all the 'path' properties in a single string.

This is what I have tried, but it is not giving me the desired output:

function getEndPoints(prova) {
let endpoints: string = '';
prova.forEach((r) => {
    if (r.path) {
        endpoints += r.path;
        if(r.children){
            r.children.forEach((s) => {
                if (s.path) {
                    endpoints += s.path;
                }
                if (s.children){
                    s.children.forEach((z) =>{
                        if (z.path){
                            endpoints += z.path;
                        }
                    });
                }
            });
        }
    }
});
console.log(endpoints);

I am struggling to figure out how to loop through an array of objects deeply and continuously. Desired output in this case: '/Root/Son/Grandson/Boh'.

Currently, I am unsure of how to navigate deeply within the array of objects.

Answer №1

There is a possibility for your input structure to yield multiple results...

For example, I have made modifications below to demonstrate that /Grandson now has multiple children:

let prova = [
{
    path: '/Root',
    method: 'GET',
    children: [
        {
            path: '/Son',
            method: 'GET',
            children: [
                {
                    path: '/Grandson',
                    method: 'GET',
                    children: [
                        {
                            path: '/Boh',
                            method: 'GET',
                            activeMessage: 'End',
                        },
                        {
                            path: '/AnotherBoh',
                            method: 'GET',
                            activeMessage: 'End',
                        }
                    ],
                }
            ],
        }
    ],
    middleware: [
        'middleware1',
    ]
}];

function getLinks(p) {
  const arr = [];
  function inner(p, root) {
    p.forEach((x) => {
      const newroot = root + x.path;
      if (!x.children) {
        arr.push(newroot);
      } else {
        inner(x.children, newroot);
      }
    });
  }
  inner(p, "");
  return arr;
}

console.log(getLinks(prova));

Answer №2

Here is an alternative approach inspired by @Keith's response. This method returns the list of paths as an array of strings instead of simply logging them.

let sample = [{
    path: '/Root',
    children: [{
        path: '/Son',
        children: [{
            path: '/Grandson',
            children: [{
                path: '/Boh',
            }, {
                path: '/AnotherBoh',
                children: [{
                   path: '/Foo'
                }, {
                  path: '/Bar'
                }]
            }]
        }]
    }, {
        path: '/AnotherSon',
    }],
    middleware: ['middleware1']
}];

function retrievePaths(nodes, base = "", collection = []) {
  return nodes.map((node) => {
    if (node.children) {
      retrievePaths(node.children, base + node.path, collection);
    } else {
      collection.push(base + node.path);
    }
    return collection
  }).reduce((a, b) => a.concat(b), []); // removes an (unnecessary?) level of nesting
}

console.log(retrievePaths(sample));

Please note that some properties have been removed for brevity, while nesting has been added at various levels for testing purposes.


Update

Here's a more concise version of the same concept:

const flat = arr => arr.reduce((out, item) => out.concat(item), [])

const retrievePaths = (nodes, base = "", collection = []) => flat(nodes.map((node) => ('children' in node) 
    ? retrievePaths(node.children, base + node.path, collection)
    : collection.concat(base + node.path)
))

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

Using a combination of nested fetch() and array.map() does not allow for the return

My previous coding experience didn't present any issues with rendering HTML. Typically, I only needed to use one fetch() function. However, in this particular scenario, it appears that I require two fetch calls. The first fetch retrieves a product ID ...

How can we achieve the same functionality as React Native's { flex: 1 } in React JS?

I've been diving into React Native development, and now I'm exploring React.js for web applications. However, I'm facing a challenge in creating a simple View that takes up the entire screen to begin experimenting with different components. ...

How can I stop and hover over time in AngularJs Interval?

Within my UI, I have a time element that is continuously updated using AngularJS Interval. Even the milliseconds are constantly running. Is it possible to implement a feature where the time pauses when hovering over it? Any assistance would be greatly appr ...

Utilizing JSTL: Executing a function within <script> through the c:set tag in JSTL

Can someone help me with this code snippet? <c:set var="cls" value="${myFunction(param)}"/> ..... <script> function myFunction(param) { if(param == true) { return "aaa"; } else { return "bbb"; ...

iterate through the elements in the array

When accessing the 'date' key values from rows of a database table, I am able to echo these values without any issue. $res = $mysqli->query("SELECT * FROM alfred ORDER BY id ASC"); $row = $res->fetch_all(MYSQLI_ASSOC); foreach ($row as $k ...

`Is there a way to repurpose generic type?`

For instance, I have a STRING type that is used in both the test and test2 functions within the test function. My code looks like this: type STRING = string const test = <A = STRING>() => { test2<A>("0") } const test2 = <B& ...

Selecting options using AngularJS to parse through a list

I am faced with a challenge involving a collection of strings representing years. Here is an example: $scope.years = ["2001", "2002", "2003", ...]; My goal is to display these values in a select tag within a web page. However, whenever I attempt this usi ...

I am unable to find any resolution, so to speak

Despite reading numerous posts and trying different examples on my own, I still can't grasp this particular question that has been asked many times before. My struggle lies in returning images from various folders and processing them individually in a ...

Issue with ng-true-value in AngularJS version 1.6.1 - not functioning as expected

Recently, I delved into AngularJS and followed an online tutorial that showcased how to utilize ng-true-value and ng-false-value. Here's the snippet: <!DOCTYPE html> <html lang="en"> <head> <script src="https://ajax.googleapis ...

Monitoring Unread Message Totals in Twilio Chat

Seeking an efficient method to retrieve and update the count of unread messages in Twilio chat. I have explored similar questions and answers on other platforms, such as this one, which suggested looping through the Channel's array and utilizing Messa ...

Sharing the state of a button group across different tabs using Bootstrap 5 and JQuery (or pure JavaScript): A complete guide!

Creating a tabbed web page using Bootstrap 5 nav-tabs for the front end and JQuery for the back end. I aim to have a single radio button group displayed on all tabs, with the state of the group persisting across tab changes. Currently, both tabs display t ...

Utilize nested object models as parameters in TypeScript requests

Trying to pass request parameters using model structure in typescript. It works fine for non-nested objects, but encountering issues with nested arrays as shown below: export class exampleModel{ products: [ { name: string, ...

Is it possible to have the Save Success Alert fade out only once?

After incorporating this code snippet, I implemented a fade effect on the success alert whenever it is triggered. However, I noticed that the fade effect only occurs the first time I click "save". Subsequent clicks do not trigger the fade effect, causing ...

Textures have been added by the user in the three.js platform

Click here to access the jsFiddle adaptation of this problem. In my quest to develop a cutting-edge 3D web application, I aim to allow users to choose an image file from their device: <input id="userImage" type="file"/> Once a file is selected, th ...

What steps can I take to prevent a JavaScript element from clearing everything when clicked?

After clicking on "add more," the first delete function works correctly, but the subsequent delete element deletes everything on the page. I suspect there may be an issue with the 'ele' variable in the JavaScript code. Since I am not very experie ...

Experiencing issues with the redirect button on the navigation bar of my website

Video: https://youtu.be/aOtayR8LOuc It is essential that when I click a button on my navigation bar, it will navigate to the correct page. However, since the same nav bar is present on each page, it sometimes tries to redirect to the current page multiple ...

Implementing Angular checkbox repetition controlled from an external controller

I'm looking to streamline my controller by setting a variable from outside the controller to populate my checkbox list. Can this be done? Check out my current code snippet here: http://jsfiddle.net/ilmansg/Lx37kr3e/1/ VIEW HTML <div ng-controlle ...

What is the best way to make the sidebar occupy the entire space?

Learn about creating sticky footers using this method and check out an example here. * { margin:0; } html, body { height:100%; } #wrap { min-height:100%; height:auto !important; height:100%; margin:0 0 -47px; } #side { float:left; backgro ...

Is there a way to verify the existence of a specific error in the console?

There seems to be a conflict between a WordPress plugin or code left behind by the previous programmer, causing the WordPress admin bar to always remain visible. While no error is triggered for admins, visitors may encounter a console error. My goal is to ...

Discovering the quantity of identical elements within a JavaScript array

Looking for some assistance in solving a JavaScript problem as I am relatively new to the language: I have an array and I need help in determining the count of identical values. Below is my array: var arr = ["red", "blue", "green", "red", "red", "gray"] ...