faienz93
faienz93

Reputation: 178

How to merge Array of Objects based on the same value?

I have this array of Objects:

var array = [{
    country: "Austria",
    name: "2019-01-04T23:00:00.000Z",
    value: "1"
  },
  {
    country: "Austria",
    name: "2019-01-11T23:00:00.000Z",
    value: "3"
  },
  {
    country: "Austria",
    name: "2019-01-18T23:00:00.000Z",
    value: "1"
  }
]

I want manipulate this to achieve this result:

var array = [{
  country: "Austria",
  series: [{
      name: "2019-01-04T23:00:00.000Z",
      value: "1"
    },
    {
      name: "2019-01-11T23:00:00.000Z",
      value: "3"
    },
    {
      name: "2019-01-18T23:00:00.000Z",
      value: "1"
    }
  ]
}]

I read many questions but none helped me.

Upvotes: 1

Views: 1390

Answers (4)

adiga
adiga

Reputation: 35202

You could loop thorugh the array. Use destructuring to get country and rest of the properties separately. Add each unique country to group object as key and push the rest object to the series array. Then use Object.values() to get the values as an array

const array=[{country:"Austria",name:"2019-01-04T23:00:00.000Z",value:"1"},{country:"Austria",name:"2019-01-11T23:00:00.000Z",value:"3"},{country:"Austria",name:"2019-01-18T23:00:00.000Z",value:"1"}];

const group = {};

array.forEach(({ country, ...rest }) => {
  group[country] = group[country] || { country, series: [] };
  group[country].series.push(rest)
})

console.log(Object.values(group))

Upvotes: 1

Goran
Goran

Reputation: 3410

Here is functional solution without for loops and mutable variables:

const result = array.reduce((carry, item) => {
    if (!carry.includes(item.country)) {
        carry.push(item.country);
    }
    return carry;
}, []).map(country => {
    return {
        country: country,
        series: array.filter(item => item.country === country).map(item => {
            return {
                name: item.name,
                value: item.value
            };
        })
    };

Upvotes: 1

zhulien
zhulien

Reputation: 5695

This should do:

var map = {};

for(var entity of array) {
    if(!map[entity.country]) {
        map[entity.country] = {
            country: entity.country,
            series: [
                {
                    name: entity.name,
                    value: entity.value
                }
            ]
        };
    }
    else {
        map[entity.country].series.push({
            name: entity.name,
            value: entity.value            
        });
    }
}

var mappedArray = Object.values(map);

Upvotes: 1

German Burgardt
German Burgardt

Reputation: 385

You can do something like:

const result = array
    .map(
        c => ({
            country: c.country,
            series: array
                .filter(d => d.country === c.country)
                .map(
                    d => ({
                        name: d.name,
                        value: d.value
                    })
                )
        })
    )

Upvotes: 0

Related Questions