简体   繁体   中英

How to group by and sum an array of objects javascript?


const array = [
  {
      "data": {
          "qty": "5",
          "toy": {
              "id": 3,
          },
          "available": "yes",
      }
  },
  {
      "data": {
          "qty": "5",
          "toy": {
              "id": 10,
          },
          "available": "no"
      }
  },
  {
      "data": {
          "qty": "59",
          "toy": {
              "id": 10,
          },
          "available": "yes",
      }
  },
  {
      "data": {
          "qty": "5",
          "toy": {
              "id": 3,
          },
          "available": "yes",
      }
  }
]


var result = [];
array.reduce(function(res, value) {
  if (!res['data']['toy'] || !res['data']['toy']['data']) {
    res['data'] = {...value['data'] };
    result.push(res['data'])
  }
  if (res['data']['available'] === value['data']['available'] && res['data']['toy']['id'] === value['data']['toy']['id']) {
    res['data']['qty'] = parseInt(res['data']['qty']) + parseInt(value['data'].qty)
  }
  return res;
}, {'data': {}});

console.log(result)

I am working on a js project and I need a bit of help here. From the array, How to get a new array that has qty as the sum of the other qty value which data.toy.id and available same. ie I want the below array. My code is not working as excepted. Changes to the same or new code are also fine. Thank you.

const array = [
  {
      "data": {
          "qty": "10",
          "toy": {
              "id": 3,
          },
          "available": "yes",
      }
  },
  {
      "data": {
          "qty": "5",
          "toy": {
              "id": 10,
          },
          "available": "no"
      }
  },
  {
      "data": {
          "qty": "59",
          "toy": {
              "id": 10,
          },
          "available": "yes",
      }
  }
]

You group the array into an object, where the keys are concatenation of available and id properties and finally transform the object back to an array using Object.values .

 const array = [ { data: { qty: "5", toy: { id: 3 }, available: "yes" } }, { data: { qty: "5", toy: { id: 10 }, available: "no" } }, { data: { qty: "59", toy: { id: 10 }, available: "yes" } }, { data: { qty: "5", toy: { id: 3 }, available: "yes" } }, ], result = Object.values( array.reduce((r, { data }) => { const k = data.available + data.toy.id; if (r[k]) { r[k].data.qty = String(Number(r[k].data.qty) + Number(data.qty)); } else { r[k] = { data }; } return r; }, {}) ); console.log(result);

You can use Array#reduce() to create arrayHash object using as keys: ${c.data.toy.id}-${c.data.available}

Code:

 const array = [{data: {qty: '5',toy: {id: 3,},available: 'yes',},},{data: {qty: '5',toy: {id: 10,},available: 'no',},},{data: {qty: '59',toy: {id: 10,},available: 'yes',},},{data: {qty: '5',toy: {id: 3,},available: 'yes',},},] const arrayHash = array.reduce((a, { data }) => { const key = `${data.toy.id}-${data.available}` a[key] = a[key] || { data: { ...data, qty: 0 } } a[key].data.qty = (+a[key].data.qty + +data.qty).toString(); return a }, {}) const result = Object.values(arrayHash) console.log(result)

I'd suggest using Array.reduce() to group by a key , which will be combined value of the toy id and the available property.

We'd create a map of all toys based on this key, summing the quantity for each.

Finally, we'll use Object.values() to convert back into an array.

 const array = [ { "data": { "qty": "5", "toy": { "id": 3, }, "available": "yes", } }, { "data": { "qty": "5", "toy": { "id": 10, }, "available": "no" } }, { "data": { "qty": "59", "toy": { "id": 10, }, "available": "yes", } }, { "data": { "qty": "5", "toy": { "id": 3, }, "available": "yes", } } ]; const result = Object.values(array.reduce((acc, { data: { qty, toy, available } }) => { const key = `${toy.id}-${available}`; acc[key] = acc[key] || { data: { qty: 0, toy, available } }; acc[key].data.qty += Number(qty); return acc; }, {})) console.log('Result:', result)
 .as-console-wrapper { max-height: 100% !important; }

I'd use just reduce

 const a1 = [ { "data": { "qty": "5", "toy": { "id": 3, }, "available": "yes", } }, { "data": { "qty": "5", "toy": { "id": 10, }, "available": "no" } }, { "data": { "qty": "59", "toy": { "id": 10, }, "available": "yes", } }, { "data": { "qty": "5", "toy": { "id": 3, }, "available": "yes", } } ] const a2 = a1.reduce((acc, it) => { let found = acc.find( dp => dp.data.toy.id === it.data.toy.id && dp.data.available === it.data.available ) if(found){ found.data.qty = ( Number(found.data.qty) + Number(it.data.qty) ).toString() } else acc.push(it) return acc }, []) console.log(JSON.stringify(a2, null,2))

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