Home > Net >  Best way to convert and array of objects into a simplistic array
Best way to convert and array of objects into a simplistic array

Time:09-24

I have an array of objects. Basically, each object has 2 keys named id and value. Now I have to convert this array into an another array but with respect to ids.

Eg

const arr1 = [{
    "month": "April",
    "values": [{
       "id": "rice",
       "value": 10
    },
    {
       "id": "wheat",
       "value": 20
    },
    {
       "id": "corn",
       "value": 30
    }]
},{
    "month": "May",
    "values": [{
       "id": "rice",
       "value": 40
    },
    {
       "id": "wheat",
       "value": 50
    },
    {
       "id": "corn",
       "value": 60
    }]
},{
    "month": "June",
    "values": [{
       "id": "rice",
       "value": 70
    },
    {
       "id": "wheat",
       "value": 80
    },
    {
       "id": "corn",
       "value": 90
    }]
}]

I want to take out values and make it something like

const arr2 = [{
   id: "rice",
   values: [10,40,70],
},{
   id: "wheat",
   values: [20,50,80],
},{
   id: "corn",
   values: [30,60,90],
}]

arranged in order of dates.

What I have tried

const ids = arr1[0].values.map(value => value.id);
const arr2 = ids.map(id => {
    return {
        id,
        values:[]
    }
}

I am unable to think of how to fill the values. The most obvious way will require 3 loops which should not be a good idea.

What should i do?

CodePudding user response:

const arr2 = arr1.flatMap(x => x.values);
arr2.map(x => ({ 
    id: x.id, 
    value: arr2
        .filter(y => y.id === x.id)
        .map(y => y.value) 
}));

CodePudding user response:

Here's one approach:

const extractValues = months => 
  Object .entries (months 
    .flatMap (({values}) => values)
    .reduce ((a, {id, value}) => ({...a, [id]: [...(a [id] || []), value]}), {})
  ) .map (([id, values]) => ({id, values}))

const months = [{month: "April", values: [{id: "rice", value: 10}, {id: "wheat", value: 20}, {id: "corn", value: 30}]}, {month: "May", values: [{id: "rice", value: 40}, {id: "wheat", value: 50}, {id: "corn", value: 60}]}, {month: "June", values: [{id: "rice", value: 70}, {id: "wheat", value: 80}, {id: "corn", value: 90}]}]

console .log (extractValues (months))
.as-console-wrapper {max-height: 100% !important; top: 0}

We start by flat-mapping the original array to combine all the value nodes in a single array, so it will contain rice/10, wheat/20, corn/30, rice/40, ..., corn/90, in objects like your original: {id: 'rice', value: 10}.

Then with reduce, we combine those into

{
  rice: [10, 40, 70],
  wheat: [20, 50, 80],
  corn: [30, 60, 90]
}

We use Object.entries to extract that into

[
  ['rice', [10, 40, 70]],
  ['wheat', [20, 50, 80]],
  ['corn', [30, 60, 90]]
]

and then we map over them, converting this into your expected output structure.

We retain the order of the inputs, and don't try to resort by your month. That would not be much more work, but it's a reasonable guess that the data will already be sorted that way.

  • Related