Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to merge objects with same id, inside the same array?

Tags:

javascript

I need to parse an API to my application, to get this array of objects:

parsedPlan = [{
id: "start"
small_degressive_rate: 0.22
small_hourly_rate: 2
large_degressive_rate: 0.27
large_hourly_rate: 4.2
},
{
id: "bonus"
small_degressive_rate: 0.21
small_hourly_rate: 1.75
large_degressive_rate: 0.26
large_hourly_rate: 3.55
},
...
]

I tried to filter api data to get the values needed, and then push to a new array: parsedPlan.

import axios from 'axios';

export function parsedPlan() {
  const api = '##########';

  const element = {}; 
  const parsedPlan = [];

  element.id = '';
  element.small_hourly_rate = '';
  element.small_degressive_rate = '';
  element.large_hourly_rate = '';
  element.large_degressive_rate = '';


  axios.get(`${api}/car_prices`)
    .then((response) => {
      const smallPlan = response.data.filter(plan => plan.size == 'S');
      smallPlan.map((plans) => {
        parsedPlan.push({
          id: plans.plan,
          small_hourly_rate: plans.hourly_rate,
          small_degressive_rate: plans.distance_degressive_rate,
        });
      });
      const largePlan = response.data.filter(plan => plan.size == 'XL');
      largePlan.map((plans) => {
        parsedPlan.push({
          id: plans.plan,
          large_hourly_rate: plans.hourly_rate,
          large_degressive_rate: plans.distance_degressive_rate,
        });
      });
    })
    .catch((error) => {
      console.log(error);
    });

  return parsedPlan;
}

For now my parsedPlan looks like this:

parsedPlan = [{
id: "start"
small_degressive_rate: 0.22
small_hourly_rate: 2
},
{
id: "bonus"
small_degressive_rate: 0.21
small_hourly_rate: 1.75
},
...
{
id: "start"
large_degressive_rate: 0.27
large_hourly_rate: 4.2
},
{
id: "bonus"
large_degressive_rate: 0.26
large_hourly_rate: 3.55
},
...
]

And I would like to merge objects with same id. Any ideas how I can get the expected result ?

like image 530
Pedro Avatar asked Dec 06 '25 05:12

Pedro


2 Answers

You can use the reduce function and in the accumulator array check if there exist an object whose id matches.

If it matches then in that index add a new object which will contain all the keys

let data = [{
    id: "start",
    small_degressive_rate: 0.22,
    small_hourly_rate: 2
  },
  {
    id: "bonus",
    small_degressive_rate: 0.21,
    small_hourly_rate: 1.75
  }, {
    id: "start",
    large_degressive_rate: 0.27,
    large_hourly_rate: 4.2
  },
  {
    id: "bonus",
    large_degressive_rate: 0.26,
    large_hourly_rate: 3.55
  }
]



let newData = data.reduce(function(acc, curr) {
  let findIndex = acc.findIndex(function(item) {
    return item.id === curr.id
  })

  if (findIndex === -1) {
    acc.push(curr)
  } else {
    acc[findIndex] = (Object.assign({}, acc[findIndex], curr))

  }


  return acc;
}, [])


console.log(newData)
like image 127
brk Avatar answered Dec 08 '25 19:12

brk


"use reduce function. Create a Object with id as key. Check if id exists or not, if not then create key with name of id else spread the rest values in the existing object and later use Object.Values() to exclude the keys"

const input = [
    {
        id: "start",
        small_degressive_rate: 0.22,
        small_hourly_rate: 2
    },
    {
        id: "bonus",
        small_degressive_rate: 0.21,
        small_hourly_rate: 1.75
    },
    {
        id: "start",
        large_degressive_rate: 0.27,
        large_hourly_rate: 4.2
    },
    {
        id: "bonus",
        large_degressive_rate: 0.26,
        large_hourly_rate: 3.55
    },
];

const output = Object.values(input.reduce((accu, {id, ...rest}) => {
    if(!accu[id]) accu[id] = {};
    accu[id] = {id, ...accu[id], ...rest};
    return accu;
}, {}));

console.log(output);
like image 35
random Avatar answered Dec 08 '25 19:12

random