Nested Array Filter/Mapping

Viewed 42

Probably a basic question, but I've been blocked for a day now on this. I am trying to get the correct map/filter from the following array:

[{
    "id": 1,
    "description": "Electric",
    "subUtilityTypes": [{
        "id": 5,
        "description": "Grid"
      },
      {
        "id": 6,
        "description": "Solar"
      }
    ]
  },
  {
    "id": 2,
    "description": "Gas",
    "subUtilityTypes": [{
        "id": 7,
        "description": "Heating Oil"
      },
      {
        "id": 8,
        "description": "Natural Gas"
      },
      {
        "id": 11,
        "description": "Propane"
      }
    ]
  }
]

I want to get the id and description inside all subUtilityTypes.

This is what I've been trying:

this.options = arr1.map((parent) => {
  return {
    id: parent.id,
    name: parent.subUtilityTypes.flatMap((child) => {
      return child.description;
    })
  };
});

My problem with what I am trying is that instead of creating separate objects I am getting parent id and list of child names like this:

[{
    "id": 1,
    "name": [
      "Grid",
      "Solar"
    ]
  },
  {
    "id": 2,
    "name": [
      "Heating Oil",
      "Natural Gas",
      "Propane"
    ]
  }
]

Expected result should look like this:

[{
    "id": 5,
    "name": [
      "Grid"
    ]
  },
  {
    "id": 6,
    "name": [
      "Solar"
    ]
  },
  {
    "id": 7,
    "name": [
      "Heating Oil"
    ]
  }
]
3 Answers

Firstly use flatMap to get subUtilityTypes, then map entries:

const input = [{id:1,description:"Electric",subUtilityTypes:[{id:5,description:"Grid"},{id:6,description:"Solar"}]},{id:2,description:"Gas",subUtilityTypes:[{id:7,description:"Heating Oil"},{id:8,description:"Natural Gas"},{id:11,description:"Propane"}]}];

const res = input.flatMap(e => e.subUtilityTypes)
                 .map(e => ({ id: e.id, name: [e.description] }))
                 
console.log(res)
.as-console-wrapper { max-height: 100% !important; top: 0; } /* ignore this */

Map only arr1 by returning only subUtilityTypes and then map it to get the desired result :

 arr1.flatMap(item=>item.subUtilityTypes)
       .map(item=>({id:item.id,name:[item.description]}))

let arr1=[
    {
        "id": 1,
        "description": "Electric",
        "subUtilityTypes": [
            {
                "id": 5,
                "description": "Grid"
            },
            {
                "id": 6,
                "description": "Solar"
            }
        ]
    },
    {
        "id": 2,
        "description": "Gas",
        "subUtilityTypes": [
            {
                "id": 7,
                "description": "Heating Oil"
            },
            {
                "id": 8,
                "description": "Natural Gas"
            },
            {
                "id": 11,
                "description": "Propane"
            }
        ]
    }
]

let options=arr1.flatMap(item=>item.subUtilityTypes).map(item=>({id:item.id,name:[item.description]}))

console.log(options)

You can also use reduce to achieve the same result.

arr.reduce((acc, curr) => [...acc,...curr.subUtilityTypes.map((o) => ({ id: o.id, name: [o.description] })),],[])

const arr = [
  {
    id: 1,
    description: "Electric",
    subUtilityTypes: [
      {
        id: 5,
        description: "Grid",
      },
      {
        id: 6,
        description: "Solar",
      },
    ],
  },
  {
    id: 2,
    description: "Gas",
    subUtilityTypes: [
      {
        id: 7,
        description: "Heating Oil",
      },
      {
        id: 8,
        description: "Natural Gas",
      },
      {
        id: 11,
        description: "Propane",
      },
    ],
  },
];

const result = arr.reduce((acc, curr) => [...acc,...curr.subUtilityTypes.map((o) => ({ id: o.id, name: [o.description] })),],[]);
console.log(result);

Related