Mai Rich
Mai Rich

Reputation: 81

Javascript array of objects group and sum items

I'm struggling with getting the desired output of Array of objects. So let's I have this Array of object:

var cars = [
    { make: 'audi', model: 'r8', quantity: '5' }, 
    { make: 'audi', model: 'rs5', quantity: '10'}, 
    { make: 'ford', model: 'mustang', quantity: '3' }, 
    { make: 'kia', model: 'optima', quantity: '9' },
    { make: 'audi', model: 'rw7', quantity: '2' },
    { make: 'ford', model: 'fusion', quantity: '7' }
],

The desired Output:

var cars = [
    { make: 'audi', sumQuantity: '17' }, 
    { make: 'ford', sumQuantity: '10' }, 
    { make: 'kia',  sumQuantity: '9' }
],

I tried to map through them but didn't solve my problem, hope you guys help out here! Thanks.

Upvotes: 2

Views: 1744

Answers (4)

Rodrigo Rodrigues
Rodrigo Rodrigues

Reputation: 8536

I was looking for a quick, almost "one-liner" answer in this thread, provided that this is a trivial but common exercise.

I couldn't find any for my like. The other answers are fine but I am not much into boilerplate.

So, let me add one, then:

obj = cars.reduce((c,{make:m,quantity:q})=>({...c,[m]:(c[m]||0)+Number(q)}),{})
output = Object.entries(obj).map(([m,q])=>({make:m,sumQuantity:q.toString()}))

var cars = [
    { make: 'audi', model: 'r8', quantity: '5' }, 
    { make: 'audi', model: 'rs5', quantity: '10'}, 
    { make: 'ford', model: 'mustang', quantity: '3' }, 
    { make: 'kia', model: 'optima', quantity: '9' },
    { make: 'audi', model: 'rw7', quantity: '2' },
    { make: 'ford', model: 'fusion', quantity: '7' }
]

obj = cars.reduce((c,{make:m,quantity:q})=>({...c,[m]:(c[m]||0)+Number(q)}),{})
output = Object.entries(obj).map(([m,q])=>({make:m,sumQuantity:q.toString()}))

console.log(output)

Upvotes: 0

Jakub Kylián
Jakub Kylián

Reputation: 319

This works fine

Object.values(
  cars.reduce((agg, car) => {
    if (agg[car.make] === undefined) agg[car.make] = { make: car.make, sumQuantity: 0 }
    agg[car.make].sumQuantity += +car.quantity
    return agg
  }, {})
)

Upvotes: 3

Vaibhav
Vaibhav

Reputation: 602

You could do something like this

function desiredOutput(cars) {
  var output = []

  for (let i = 0 ; i < cars.length ; i++) {
    output.push({"make": cars[i].make, "sumQuantity": "Value based on your logic."});
  }

  return output 
}

var cars = [
    { make: 'audi', model: 'r8', quantity: '5' }, 
    { make: 'audi', model: 'rs5', quantity: '10'}, 
    { make: 'ford', model: 'mustang', quantity: '3' }, 
    { make: 'kia', model: 'optima', quantity: '9' },
    { make: 'audi', model: 'rw7', quantity: '2' },
    { make: 'ford', model: 'fusion', quantity: '7' },
]

let output = desiredOutput(cars);

Upvotes: 0

The Otterlord
The Otterlord

Reputation: 2185

Probably not the most concise solution as I'm no JavaScript master.

First we get all the cars added up in a slightly easier to handle format. Then we rebuild it into the format requested above.

var newCars = [];
var makes = {};

for (var i=0; i<cars.length; i++) {
    var car = cars[i];
    var keys = Object.keys(makes)
    if (keys.includes(car.make)) {
        makes[car.make] += parseInt(car.quantity)
    } else {
        makes[car.make] = parseInt(car.quantity)
    }
}

var keys = Object.keys(makes)

for (var i=0; i<keys.length; i++) {
    newCars.push({make: keys[i], sumQuantity: makes[keys[i]]})
}

Upvotes: 1

Related Questions