0

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. i.e. 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",
      }
  }
]

1

4 Answers 4

0

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);

Sign up to request clarification or add additional context in comments.

Comments

0

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; }

Comments

0

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)

1 Comment

Your solution does not add up the quantities of similar items. Replacing this a[key].data.qty = c.data.qty with a[key].data.qty += c.data.qty should make it work.
0

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))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.