Calculate the total of JSON objects while eliminating duplicates in an array

Below is an array of objects:

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

Desired 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 code provides the sum of properties like quantity, receivedQty and shippedQty based on grouping of batchNumber and item value. It correctly groups the first two items by batchNumber and item, but not the last two based on item value only.

groupedVariantLineItems() {
      // Code for grouping variants
  }
  

The current code correctly outputs the first two line items grouped by batchNumber, but not the last two. Adjustments are needed for correct grouping based on item value.

Answer №1

Is this method not functioning 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 will present a more organized version in the following revision.

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

Answer №2

let statistics = {totalQuantity: 0};
lineItems.filter((item) => typeof item.batchNumber !== 'undefined').forEach((item) => statistics.totalQuantity += item.quantity);
console.log(statistics); // {totalQuantity: 50}

Answer №3

Here is how the else if condition ought to be structured:

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

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

After reaching a total of 20 entries, req.body will automatically convert the array into an

I have the ability to dynamically add properties to my form: <form action=""> <div class="property"> <label>Name : <input type="text" name="properties[1][name]"></label> <label>Order : <input type="text" na ...

What is the process for transforming FormData into an Object and then converting it into a JSON string

Is there a way to convert FormData into an object and then use JSON.stringify on it? I suspect that my API isn't populating values correctly because it expects data in JSON format. handleSubmit: handleSubmit(event) { event.preventDefault(); ...

Tips for executing gulp tasks in the command line

As a newcomer to Gulp, I've encountered an issue with executing a task named task1 in my gulp.js file. When I enter "gulp task1" in the command line, it opens the gulp.js file in Brackets editor instead of running the task as expected. Can anyone offe ...

utilizing jquery for multidimensional json arrays

Feeling frustrated as I try to grasp the intricacies of JSON data structure. An undefined multidimensional array is coming from a web API, and its layout looks like this: { "totalCount": 30, "entries": [{"title": "item1","description": "your amazing item ...

Issue with capybara-webkit not sending data parameters in $.ajax delete request

When I use capybara-webkit to execute my ajax DELETE requests, I am noticing that the data parameters are not being sent to the controller. However, when I run the test suite with selenium, the data parameters do get sent and the test passes. Here is a sni ...

Using Node.js to parse XLSX files and generate JSON output

Recently, I came across an extremely well-documented node_module known as js-xlsx Curious: How can I convert xlsx to json format? This is the structure of the excel sheet: The desired json output should resemble the following: [ { "id": 1, "H ...

Tips for sending a Json array to a servlet

[DUPICATE] Here is the JSON code I am using for my POST request: var data_create = JSON.stringify($("#form_create_delegate").serializeArray()); alert("data_create content" + data_create); // console.log(data_create) $.ajax({ ...

Troubles with concealing dropdown menu when hovering

I have noticed that this issue has been raised before, but none of the solutions provided seem to fix my problem specifically. The submenu in my menu is not functioning as intended. It should be displayed when hovered over and hidden when not being hovere ...

I am interested in organizing a three-dimensional array using JavaScript

Just the other day, I posted a question on PHP, but now I need similar help for JavaScript. Here is my array : var inboxMessages = { 105775: { 0: { 'id': 85, 'thread_id': 105775, ' ...

Invoke a function of a child component that resides within the <ng-content> tag of its parent component

Check out the Plunkr to see what I'm working on. I have a dynamic tab control where each tab contains a component that extends from a 'Delay-load' component. The goal is for the user to click on a tab and then trigger the 'loadData&apo ...

What purpose does @ViewChild serve if we are unable to modify or interact with its properties from the Parent Component?

I have two main components - home and about. Within both of these, I am including a third component called hearts. Currently, I am manipulating the value of the 'age' property in the hearts component (initially set to '23') using @ViewC ...

How to implement scroll spy in Bootstrap 4 to highlight parent li elements?

I have a bootstrap4 menu set up like this: <ul class="navbar-nav ml-auto"> <li class="nav-item"><a class="nav-link" href="#introduction">INTRODUCTION <span class="sr-only">(current)</span></a></li> </ul> Th ...

Can we establish the set values for a function's parameter in advance?

I need to define the available values for a function's parameter in this way: let valueList = [ 'val1', 'val2', 'val3', ]; let getSomething = (parameter: valueList) => { // do something } I want the con ...

Tips on how to loop through every piece of information within a table

<table class="table_style" id="table"> <thead> <tr> <th>Id</th> <th>Name</th> <th>Email</th> <th>Phone</th> </tr> </thead> <tbody> ...

What is the best way to implement lazy loading of images that have not been downloaded in a JavaFX WebView?

Currently, I am in the process of developing an email client application using JavaFX WebView to showcase email HTML files. In order to enhance its responsiveness and speed, my goal is to display inline images in emails as they are downloaded locally. Duri ...

The one-time binding notation does not seem to be functioning as expected in AngularJS version 1.6.4

For our application, we are utilizing AngularJS 1.6.4 to display a large number of rows on a single page. However, when it reaches around 7K entries, the page starts hanging. To tackle this issue, we have opted for one-time binding for those specific pages ...

Surprising Media Component Found in URL Parameters within the design

Exploring the page structure of my Next.js project: events/[eventId] Within the events directory, I have a layout that is shared between both the main events page and the individual event pages(events/[eventId]). The layout includes a simple video backgro ...

updating firebase data using Angular

Currently, I am attempting to insert a new object into my Firebase database export class AppComponent { courses$: AngularFireList<any[]>; course$;ang author$ constructor(db: AngularFireDatabase) { this.courses$ = db.list('/courses ...

Having trouble loading an image after successfully connecting to an API with react.js

I've been working on a custom fetch component to load images from the "the dog API" onto my page. However, I'm facing some issues with getting the images to display correctly. Can anyone spot what might be missing in my setup? App.js import &apo ...

Different ways to separate an axios call into a distinct method with vuex and typescript

I have been working on organizing my code in Vuex actions to improve readability and efficiency. Specifically, I want to extract the axios call into its own method, but I haven't been successful so far. Below is a snippet of my code: async updateProf ...