Home > Enterprise >  Getting all key value pairs from object into a single array
Getting all key value pairs from object into a single array

Time:04-09

I have an object as per below:

{
      items: [
        {
          id: '6978119a-481e-4ff5-bd02-2b51d2aed804',
          name: 'Car',
          items: [],
        },
        {
          id: '9cc8fe29-1106-4f3e-958d-250ca74cc1e8',
          name: 'Toolbox',
          items: [
            {
              id: '1764e295-4ee7-4455-80b4-ea011e111785',
              name: 'Spanner',
              items: [],
            },
            {
              id: '3a2c1c78-9c97-457e-bfdd-ea13ced94406',
              name: 'Hammer',
              items: [],
            },
          ],
        },
        {
          id: 'aa41d735-ebb7-48dd-a5b0-dc6806c4ee95',
          name: 'Shed',
          items: [
            {
              id: '0a81991c-51e7-4cea-b1cf-a63ea7200744',
              name: 'Axe',
              items: [],
            },
          ],
        },
      ],
      };

I am trying to figure out two things:

  1. Get an array of objects, where the key is 'name' (e.g. below)
var array = [{name: 'Car'}, {name: 'Toolbox'}, {name: 'Spanner'}, {name: 'Hammer'}, {name: 'Shed'}, {name: 'Axe'}]
  1. Get an array of objects, where the key is 'name' but has no items below it (essentially childless) (e.g. below)
var array = [{name: 'Car'}, {name: 'Spanner'}, {name: 'Hammer'}, {name: 'Axe'}]

I attempted putting something together that iterates to a list and pushes to an array but after the 3rd nested loop, I knew I was doing something wrong.

I've also explored Object.entries but it only gets the top layer.

CodePudding user response:

var array = [];
var name;
items.forEach(item=>{
  name = item.name;
  array.push(name);
});

Output: var array = [name: 'Car', name: 'Toolbox', name: 'Spanner', name: 'Hammer', name: 'Shed', name: 'Axe']

Note: if you are using older version of js, instead of forEach loop, you can use old traditional for loop.

CodePudding user response:

You can use recursion to check all items and child items

const data = {
      items: [
        {
          id: '6978119a-481e-4ff5-bd02-2b51d2aed804',
          name: 'Car',
          items: [],
        },
        {
          id: '9cc8fe29-1106-4f3e-958d-250ca74cc1e8',
          name: 'Toolbox',
          items: [
            {
              id: '1764e295-4ee7-4455-80b4-ea011e111785',
              name: 'Spanner',
              items: [],
            },
            {
              id: '3a2c1c78-9c97-457e-bfdd-ea13ced94406',
              name: 'Hammer',
              items: [],
            },
          ],
        },
        {
          id: 'aa41d735-ebb7-48dd-a5b0-dc6806c4ee95',
          name: 'Shed',
          items: [
            {
              id: '0a81991c-51e7-4cea-b1cf-a63ea7200744',
              name: 'Axe',
              items: [],
            },
          ],
        },
      ],
      };

const getNames = (items, result = []) => {
   
   for(const item of items) {
      if(!item.items || !item.items.length) {
         // no sub-items, just push name to the result
         result.push({ name: item.name })
      } else {
         //loop through all child items to find child names
         result = getNames(item.items, result)
      }
   }
   return result
}

const finalResult = getNames(data.items)
console.log(finalResult)

Another version with concat (no result param) in recursion

const data = {
      items: [
        {
          id: '6978119a-481e-4ff5-bd02-2b51d2aed804',
          name: 'Car',
          items: [],
        },
        {
          id: '9cc8fe29-1106-4f3e-958d-250ca74cc1e8',
          name: 'Toolbox',
          items: [
            {
              id: '1764e295-4ee7-4455-80b4-ea011e111785',
              name: 'Spanner',
              items: [],
            },
            {
              id: '3a2c1c78-9c97-457e-bfdd-ea13ced94406',
              name: 'Hammer',
              items: [],
            },
          ],
        },
        {
          id: 'aa41d735-ebb7-48dd-a5b0-dc6806c4ee95',
          name: 'Shed',
          items: [
            {
              id: '0a81991c-51e7-4cea-b1cf-a63ea7200744',
              name: 'Axe',
              items: [],
            },
          ],
        },
      ],
      };

const getNames = (items) => {
   let result = []
   for(const item of items) {
      if(!item.items || !item.items.length) {
         result.push({ name: item.name })
      } else {
         result = result.concat(getNames(item.items))
      }
   }
   return result
}

const finalResult = getNames(data.items)
console.log(finalResult)

CodePudding user response:

You can get both the results just by passing an extra argument to the function according to your need:

  • Get an array of objects, where Key is 'name' but has no items below it (essentially childless): prepareData(data?.items, true)
  • Get an array of objects, where Key is 'name': prepareData(data?.items)

const data = {
  items: [{
      id: '6978119a-481e-4ff5-bd02-2b51d2aed804',
      name: 'Car',
      items: [],
    },
    {
      id: '9cc8fe29-1106-4f3e-958d-250ca74cc1e8',
      name: 'Toolbox',
      items: [{
          id: '1764e295-4ee7-4455-80b4-ea011e111785',
          name: 'Spanner',
          items: [],
        },
        {
          id: '3a2c1c78-9c97-457e-bfdd-ea13ced94406',
          name: 'Hammer',
          items: [],
        },
      ],
    },
    {
      id: 'aa41d735-ebb7-48dd-a5b0-dc6806c4ee95',
      name: 'Shed',
      items: [{
        id: '0a81991c-51e7-4cea-b1cf-a63ea7200744',
        name: 'Axe',
        items: [],
      }, ],
    },
  ],
};

const result = []

function prepareData(items, isChildless = false) {
  items?.forEach((list) => {
    if (!list ?.items?.length) {
      result.push({
        name: list?.name
      });
    } else {
      !isChildless && result.push({
        name: list?.name
      });
      prepareData(list?.items, isChildless);
    }
  })
}

prepareData(data?.items, true) // if you want to get array of object of all childless items

// prepareData(data?.items) // if you want to get array of object of items which includes items with all the children

console.log(result)

  • Related