skip to Main Content

I need all the names in an array from the mentioned object in sequence.

For Example:
const array = ["Menu 1","Menu 2","Menu 3","Menu 4","Menu 5","Menu 6"];

const array = [];

var obj = [
            {
                "name": "Menu 1",
                "link": "link 1",
                "subitems": [
                    {
                        "name": "Menu 2",
                        "link": "link 2",
                    }
                ]
            },
            {
                "name": "Menu 3",
                "link": "link 3",
                "subitems": [
                    {
                        "name": "Menu 4",
                        "link": "link 4",
                        "subitems": [
                            {
                                "name": "Menu 5",
                                "link": "link 5",
                            },
                            {
                                "name": "Menu 6",
                                "link": "link 6",
                            }
                        ]
                    }
                ]
            },
        ];

With recursive method I am able to get first level Menu items name, but I need all children menu items name is sequence.

function menuItems(obj) {
            if (!Array.isArray(obj)) {
                console.log('Array :>> ', obj);
            }
            else {
                for (let subdep of Object.values(obj)) {
                    menuItems(subdep);
                }
            }
        }

        menuItems(obj);

Please suggest which approach is better. Recursion or any other loop method?

2

Answers


  1. For your purposes recursion is probably the best solution. Just make sure that you save the name values somewhere, and exit the function when all paths are exhausted.

    const arr=[{name:"Menu 1",link:"link 1",subitems:[{name:"Menu 2",link:"link 2"}]},{name:"Menu 3",link:"link 3",subitems:[{name:"Menu 4",link:"link 4",subitems:[{name:"Menu 5",link:"link 5"},{name:"Menu 6",link:"link 6"}]}]}];
    
    // Pass in the data and initialise a output array
    function menuItems(arr, out = []) {
    
      // Iterate over the data. If it has a name prop add its
      // value to the output array. If it has a subitems array
      // pass that array, and the output array, back into the function
      for (let obj of arr) {
        if (obj.hasOwnProperty('name')) out.push(obj.name);
        if (obj.hasOwnProperty('subitems')) menuItems(obj.subitems, out);
      }
     
     // Return the output array 
     return out;
    }
    
    console.log(menuItems(arr));
    Login or Signup to reply.
  2. I’d suggest using a generator for this. This is a lazy solution, which can be interesting when you want to stop the iteration early and not waste memory on retrieving all the rest:

    function* menuItems(arr) {
        for (const {name, subitems} of arr) {
            if (name !== undefined) yield name;
            if (Array.isArray(subitems)) yield* menuItems(subitems);
        }
    }
    
    // Example run: fetching all
    const arr = [{name:"Menu 1",link:"link 1",subitems:[{name:"Menu 2",link:"link 2"}]},{name:"Menu 3",link:"link 3",subitems:[{name:"Menu 4",link:"link 4",subitems:[{name:"Menu 5",link:"link 5"},{name:"Menu 6",link:"link 6"}]}]}];
    const names = [...menuItems(arr)];
    console.log(names);
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search