Mahesh Sonvane
Mahesh Sonvane

Reputation: 11

Sum JSON Objects and remove duplicate from an array

I have below array of object:

const lineItems = [
  {
    "lineNumber": "0",
    "item": "1496",
    "itemDesc": "wertyuiasdfghj",
    "qualityReceiptHold": "N",
    "quantity": 10,
    "quantityUOM": "Unit",
    "batchNumber": "LO123678",
    "receivedQty": 5,
    "shippedQty": 10,
    "itemCode": "Packagetest1"
  },
  {
    "lineNumber": "1",
    "item": "1496",
    "itemDesc": "wertyuiasdfghj",
    "qualityReceiptHold": "N",
    "quantity": 40,
    "quantityUOM": "Unit",
    "batchNumber": "LO123678",
    "receivedQty": 4,
    "shippedQty": 20,
    "itemCode": "Packagetest1"
  },
  {
    "lineNumber": "2",
    "item": "1496",
    "itemDesc": "wertyuiasdfghj",
    "qualityReceiptHold": "N",
    "quantity": 10,
    "quantityUOM": "Unit",
    "receivedQty": 5,
    "shippedQty": 30,
    "itemCode": "Packagetest1"
  },
  {
    "lineNumber": "3",
    "item": "1496",
    "itemDesc": "wertyuiasdfghj",
    "qualityReceiptHold": "N",
    "quantity": 10,
    "quantityUOM": "Unit",
    "receivedQty": 10,
    "shippedQty": 30,
    "itemCode": "Packagetest1"
  }
];

Expecting the output:

[
  {
    "lineNumber": "0",
    "item": "1496",
    "itemDesc": "wertyuiasdfghj",
    "qualityReceiptHold": "N",
    "quantity": 50,
    "quantityUOM": "Unit",
    "batchNumber": "LO123678",
    "receivedQty": 9,
    "shippedQty": 30,
    "itemCode": "Packagetest1"
  },
  {
    "lineNumber": "2",
    "item": "1496",
    "itemDesc": "wertyuiasdfghj",
    "qualityReceiptHold": "N",
    "quantity": 20,
    "quantityUOM": "Unit",
    "receivedQty": 15,
    "shippedQty": 60,
    "itemCode": "Packagetest1"
  }
]

the sum of properties like quantity, receivedQty and shippedQty based on grouping of batchNumber and item value. In first two grouped by batchNumber and item but last two line items grouped by item value only.

groupedVariantLineItems() {
    let result = [];
    
    for( let i = 0; i < this.variantLineItems.length; i++ ) {
      let isExists = false;
      for( let j=0; j<result.length; j++ ) {
        if( typeof this.variantLineItems[i].batchNumber != "undefined" && result[j].batchNumber == this.variantLineItems[i].batchNumber && result[j].item == this.variantLineItems[i].item ) {
          isExists = true;
          result[j].quantity+= (this.variantLineItems[i].quantity!= undefined) ? Number(this.variantLineItems[i].quantity) : 0;
          result[j].shippedQty += (this.variantLineItems[i].shippedQty != undefined) ? Number(this.variantLineItems[i].shippedQty) : 0;
          result[j].receivedQty += (this.variantLineItems[i].receivedQty != undefined) ? Number(this.variantLineItems[i].receivedQty) : 0;

          result[j].quantity= ( isNaN(result[j].quantity) ) ? 0 : result[j].quantity;
          result[j].shippedQty = ( isNaN(result[j].shippedQty) ) ? 0 : result[j].shippedQty;
          result[j].receivedQty = ( isNaN(result[j].receivedQty) ) ? 0 : result[j].receivedQty;
          break;
        } else if( typeof this.variantLineItems[i].batchNumber == "undefined" && result[j].item == this.variantLineItems[i].item ) {
          isExists = true;
          result[j].quantity+= (this.variantLineItems[i].quantity!= undefined) ? Number(this.variantLineItems[i].quantity) : 0;
          result[j].shippedQty += (this.variantLineItems[i].shippedQty != undefined) ? Number(this.variantLineItems[i].shippedQty) : 0;
          result[j].receivedQty += (this.variantLineItems[i].receivedQty != undefined) ? Number(this.variantLineItems[i].receivedQty) : 0;

          result[j].quantity= ( isNaN(result[j].quantity) ) ? 0 : result[j].quantity;
          result[j].shippedQty = ( isNaN(result[j].shippedQty) ) ? 0 : result[j].shippedQty;
          result[j].receivedQty = ( isNaN(result[j].receivedQty) ) ? 0 : result[j].receivedQty;
          break;
        }
      }

      if( !isExists ) {
        result.push( this.variantLineItems[i] );
      }
    }

    return result;
  }

the above code given the correct output for first two line items which have batchNumber, but not correct for last two.

Upvotes: 0

Views: 326

Answers (3)

Nermin
Nermin

Reputation: 935

Doesn't this work for you?

const lineItems = [{
  "lineNumber": "0",
  "item": "1496",
  "itemDesc": "wertyuiasdfghj",
  "qualityReceiptHold": "N",
  "quantity": 10,
  "quantityUOM": "Unit",
  "batchNumber": "LO123678",
  "receivedQty": 5,
  "shippedQty": 10,
  "itemCode": "Packagetest1"
},
{
  "lineNumber": "1",
  "item": "1496",
  "itemDesc": "wertyuiasdfghj",
  "qualityReceiptHold": "N",
  "quantity": 40,
  "quantityUOM": "Unit",
  "batchNumber": "LO123678",
  "receivedQty": 4,
  "shippedQty": 20,
  "itemCode": "Packagetest1"
},
{
  "lineNumber": "2",
  "item": "1496",
  "itemDesc": "wertyuiasdfghj",
  "qualityReceiptHold": "N",
  "quantity": 10,
  "quantityUOM": "Unit",
  "receivedQty": 5,
  "shippedQty": 30,
  "itemCode": "Packagetest1"
},
{
  "lineNumber": "3",
  "item": "1496",
  "itemDesc": "wertyuiasdfghj",
  "qualityReceiptHold": "N",
  "quantity": 10,
  "quantityUOM": "Unit",
  "receivedQty": 10,
  "shippedQty": 30,
  "itemCode": "Packagetest1"
}
]

const sumMap = new Map()

for (entry of lineItems) {
  if (entry.batchNumber) {
    const batchAcc = sumMap.get(entry.batchNumber)

    if (batchAcc) {
      batchAcc.quantity += entry.quantity
      batchAcc.shippedQty += entry.shippedQty
      batchAcc.receivedQty += entry.receivedQty
    } else {
      sumMap.set(entry.batchNumber, entry)
    }
  } else {
    const itemAcc = sumMap.get(entry.item)

    if (itemAcc) {
      itemAcc.quantity += entry.quantity
      itemAcc.shippedQty += entry.shippedQty
      itemAcc.receivedQty += entry.receivedQty
    } else {
      sumMap.set(entry.item, entry)
    }
  }
}

const arr = Array.from(sumMap, ([, value]) => value)

console.log(arr)

I'll make a cleaner version in my next edit.

Simpler version:

const properties = ['quantity', 'shippedQty', 'receivedQty']
const sumMap = new Map()

lineItems.forEach(entry => {
  const groupBy = entry.batchNumber ? entry.batchNumber : entry.item
  const acc = sumMap.get(groupBy)

  if (acc) {
    properties.forEach(property => acc[property] += entry[property])
  } else {
    sumMap.set(groupBy, entry)
  }
})

const arr = [...sumMap].map(([, value]) => value)

console.log(arr)

Upvotes: 2

gincymathai
gincymathai

Reputation: 1

The else if condition should be as below:

} else if( typeof this.variantLineItems[i].batchNumber == "undefined" && typeof result[j].batchNumber == "undefined" && result[j].item == this.variantLineItems[i].item ) {

Upvotes: 0

ybenhssaien
ybenhssaien

Reputation: 4105

var stats = {quantity: 0};
lineItems.filter((line) => typeof line.batchNumber !== 'undefined').forEach((line) => stats.quantity += line.quantity);
console.log(stats); // {quantity: 50}

Upvotes: 0

Related Questions