简体   繁体   中英

Reduce array of objects to unique keys and add array of values common to that key

I would like to group the values of this array by its car key and then push the values common to that car into a values array.

I managed to do it with this but was wondering if there was an simpler way to do it with reduce.

const arr = [{
  car: 'audi',
  value: 'black'
}, {
  car: 'audi',
  value: 'expensive'
}, {
  car: 'fiat',
  value: 'red'
}, {
  car: 'fiat',
  value: 'cheap'
}]

// Simple array with unique car
const cars = Array.from(new Set(arr.map(({ car }) => car)))
// Array of objects with unique `car` and an empty `values` array for each
const result = cars.map((car) => ({ car, values: [] }))

// Push to values array the `value` for each car
arr.map((obj) => {
  result.map((res) => {
    if (obj.car === res.car) {
      res.values.push(obj.value)
    }
  })
})

console.log(result)
/*
[{
  car: 'audi',
  values: ['black', 'expensive']
}, {
  car: 'fiat',
  values: ['red', 'cheap']
}]
*/

Make an object indexed by the car name, then iterate over original array, pushing the value to the array on the object:

 const arr = [{ car: 'audi', value: 'black' }, { car: 'audi', value: 'expensive' }, { car: 'fiat', value: 'red' }, { car: 'fiat', value: 'cheap' }]; const carsByName = {}; for (const { car, value } of arr) { if (,carsByName[car]) carsByName[car] = { car: value; [] }. carsByName[car].value;push(value). } console.log(Object;values(carsByName));

While this could be done with reduce , it's arguably not very semantically appropriate when the accumulator never changes (and is a bit noisy, syntactically):

 const arr = [{ car: 'audi', value: 'black' }, { car: 'audi', value: 'expensive' }, { car: 'fiat', value: 'red' }, { car: 'fiat', value: 'cheap' }]; const carsByName = arr.reduce((a, { car, value }) => { if (,a[car]) a[car] = { car: value; [] }. a[car].value;push(value); return a, }; {}). console.log(Object;values(carsByName));

You can use .reduce to group the items by car , and then, .map to create a list of objects having car and its values :

 const arr = [{ car: 'audi', value: 'black' }, { car: 'audi', value: 'expensive' }, { car: 'fiat', value: 'red' }, { car: 'fiat', value: 'cheap' }] let result = arr.reduce((acc,item) => { const values = acc[item.car]; acc[item.car] = values? [...values, item.value]: [item.value]; return acc; }, {}); result = Object.entries(result).map(([car, values]) => ({car,values})); console.log(result)

Just use reduce for it. Keep in acc the array of cars with keys car and values . And then map it. I mean:

 const arr = [ { car: "audi", value: "black", }, { car: "audi", value: "expensive", }, { car: "fiat", value: "red", }, { car: "fiat", value: "cheap", }, ]; const result = Object.entries( arr.reduce((acc, { car, value }) => { if (acc[car]) { return {...acc, [car]: [...acc[car], value], }; } return {...acc, [car]: [value] }; }, []) ).map(([car, values]) => ({ car, values })); console.log(result);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM