Home > Back-end >  Parsing an array of nested objects in Javascript using recursion
Parsing an array of nested objects in Javascript using recursion

Time:08-26

I want to print all the brand names with their parent name by traversing through this array. For top level brands , parent as "None".
e.g. None : Parle, Parle : Parle Agro, Parle Agro : Frooti

let inventory = [
  {
    brand: 'Parle',
    products: [
      {
        brand: 'Parle Agro',
        products: [
          {
            brand: 'Frooti',
            products: []
          },
          {
            brand: 'Bailey',
            products: []
          }
        ]
      }
    ]
  },
  {
    brand: 'Pepsico',
    products: [
      {
        brand: 'VB',
        products: [
          {
            brand: 'Lays',
            products: []
          },
          {
            brand: 'Kurkure',
            products: [
              {
                brand: 'Mad Angles',
                products: []
              }
            ]
          }
        ]
      },
      {
        brand: 'Pepsi',
        products: []
      }
    ]
  },
  {
    brand: 'Cadbury',
    products: []
  } 
];

I have tried following approach but I'm missing out somewhere.

function brandName(obj){
for (var key in obj) {
    var item = obj[key];
    if (typeof item === "object"){
        brandName(item.products); }
} } brandName(inventory);

CodePudding user response:

Basically I've used a recursion that gets an inventory and a parent (default None) and prints the parent along with all the children. Then doing recursion for each of the children, having the child itself as parent. It's easier to see the code.

var inventory = [{brand:"Parle",products:[{brand:"Parle Agro",products:[{brand:"Frooti",products:[]},{brand:"Bailey",products:[]}]}]},{brand:"Pepsico",products:[{brand:"VB",products:[{brand:"Lays",products:[]},{brand:"Kurkure",products:[{brand:"Mad Angles",products:[]}]}]},{brand:"Pepsi",products:[]}]},{brand:"Cadbury",products:[]}]

function brandName(inventory, parent) {
  parent = parent || "None"
  inventory.forEach(function(item) {
    console.log(parent   " : "   item.brand)
    brandName(item.products, item.brand)
  })
}

brandName(inventory);
.as-console-wrapper {
  max-height: 100% !important;
}

CodePudding user response:

Here's a recursive generator that allows the caller to decide the effect. menu does a simple type analysis on the input t and responds accordingly -

function *menu(t, parent = "None") {
  switch (t?.constructor) {
    case Array:
      for (const child of t)
        yield *menu(child, parent)
      break
    case Object:
      yield [parent, t.brand]
      yield *menu(t.products, t.brand)
      break
  }
}

const inventory =
  [{brand:"Parle",products:[{brand:"Parle Agro",products:[{brand:"Frooti",products:[]},{brand:"Bailey",products:[]}]}]},{brand:"Pepsico",products:[{brand:"VB",products:[{brand:"Lays",products:[]},{brand:"Kurkure",products:[{brand:"Mad Angles",products:[]}]}]},{brand:"Pepsi",products:[]}]},{brand:"Cadbury",products:[]}]

for (const item of menu(inventory))
  console.log(item.join(":"))
.as-console-wrapper { min-height: 100%; top: 0; }

None:Parle
Parle:Parle Agro
Parle Agro:Frooti
Parle Agro:Bailey
None:Pepsico
Pepsico:VB
VB:Lays
VB:Kurkure
Kurkure:Mad Angles
Pepsico:Pepsi
None:Cadbury

If you want to collect all of the items in an array, use Array.from -

Array.from(menu(inventory))
// => [ ["None", "Parle"], ["Parle", "Parle Agro"], ...]
Array.from(menu(inventory), p => p.join(":"))
// [ "None:Pare", "Parle:Parle Agro", ...]
  • Related