Total the values of several items within the array

Here is the data I currently have:

const arrayA = [{name:'a', amount: 10, serviceId: '23a', test:'SUCCESS'},
                {name:'a', amount: 9, test:'FAIL'}, 
                {name:'b', amount: 15, serviceId: '23b', test:'SUCCESS'}]

 

(note: there are objects without a 'serviceId')

This is what I want to achieve:

 [{name:'a', amount: 19, test:'FAIL'},
  {name:'b', amount: 15, test:'SUCCESS'}]
  • I need to sum the amount field based on the name grouping.
  • The 'test' field should be set as FAIL if there is any object with the value of FAIL (grouped by name).
  • I am not concerned about the value of serviceId and do not wish to include it in the new object.

After searching, I attempted the following code:

const result = Object.values(arrayA.reduce((r, o) => (r[o.name]
  ? (r[o.name].amount += o.amount)
  : (r[o.name] = {...o}), r), {}));

However, I'm unsure how to assign the test field. Any assistance would be greatly appreciated!

Answer №1

To proceed, you must verify the value of test and make the necessary updates.

const
    array = [{ name: 'a', amount: 10, serviceId: '23a', test: 'SUCCESS' }, { name: 'a', amount: 9, test: 'FAIL' }, { name: 'b', amount: 15, serviceId: '23b', test: 'SUCCESS' }],
    result = Object.values(array.reduce((r, { name, amount, test }) => {
        if (!r[name]) r[name] = { name, amount: 0, test };
        r[name].amount += amount;
        if (test === 'FAIL') r[name].test = 'FAIL';
        return r;
    }, {}));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Answer №2

This is a simple test to check if the .test property has failed

const arrayA = [{ name: 'a', amount: 10, serviceId: '23a', test: 'SUCCESS' }, { name: 'a', amount: 9, test: 'FAIL' }, { name: 'b', amount: 15, serviceId: '23b', test: 'SUCCESS' }],
  result = Object.values(
    arrayA.reduce((r, o) => {
      r[o.name] ? (r[o.name].amount += o.amount) : (r[o.name] = { ...o })
      r[o.name].test = r[o.name].test === "FAIL" ? "FAIL" : o.test;
      return r;
    }, {})
  );

console.log(result);

Answer №3

Store the total amounts and final test results in an object, then convert them into an array.

const dataPoints = [
  { label: "alpha", value: 10, id: "30a", status: "PASS" },
  { label: "beta", value: 9, status: "FAIL" },
  { label: "gamma", value: 15, id: "30c", status: "PASS" },
];

const summary = {};

dataPoints.forEach((entry) => {
  if (!summary[entry.label]) {
    summary[entry.label] = { label: entry.label, value: 0, status: "PASS" };
  }

  summary[entry.label].value += entry.value;

  if (entry.status === "FAIL") {
    summary[entry.label].status = "FAIL";
  }
});

const finalResult = Object.values(summary);

console.log(finalResult);

Answer №4

That's a great example of data processing in JavaScript, showcasing how functions like map and reduce can simplify the process without relying on traditional loops.

It's recommended to break down the processing into steps as outlined in your description. Here's an illustration:

const arrayA = [
    {name:'a', amount: 10, serviceId: '23a', test:'SUCCESS'},
    {name:'a', amount: 9, test:'FAIL'},
    {name:'b', amount: 15, serviceId: '23b', test:'SUCCESS'}
]

// Group items by name
const byName = arrayA.reduce((ob, item) => {
    if(!(item.name in ob))
        ob[item.name] = []
    ob[item.name].push({amount: item.amount, test: item.test})
    return ob
}, {})

// Calculate total amount in each group and check for any FAILs
const sumByName = Object.keys(byName).map(name => {
    const amount = byName[name].reduce((sum, item) => sum + item.amount , 0)
    const test = byName[name].map(item => item.test)
        .includes('FAIL') ? 'FAIL': 'SUCCESS'
    return ({name, amount, test})
})

console.log(sumByName)

Lastly, I recommend checking out these videos on map and reduce (and other related content from that channel):

Answer №5

One way to achieve this is by using the Array.reduce method:

const arrayA=[{name:"a",amount:10,serviceId:"23a",test:"SUCCESS"},{name:"a",amount:9,test:"FAIL"},{name:"b",amount:15,serviceId:"23b",test:"SUCCESS"}];

let result  = arrayA.reduce((aac,{name,amount,test}) => {
    let idx = aac.findIndex(n => n.name === name)
    if( idx != -1){
        aac[idx].amount += amount;
        if(test === "FAIL")
            aac[idx].test = "FAIL"        
        return aac
    }
    aac.push({name,amount,test})
    return aac
},[])

console.log(result);
console.log(arrayA)

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

The issue of page content failing to refresh when loaded using AJAX technology

My script utilizes AJAX to dynamically load specific pages on a website. These pages display information that updates based on the current time. However, I have encountered an issue where the page content remains static when loaded through AJAX, almost as ...

Upon opening index.html in the browser, the jQuery code fails to execute, as no errors are displayed in the console

I am struggling to make a simple toggleClass() function work in jQuery and I can't seem to figure out why. This is just a beginner exercise for me with jQuery. The code works perfectly when I test it as a snippet or manually in the console, but when I ...

Is there a way to access the [class.editable] value during an Angular unit test?

For my unit test, I am trying to retrieve the value of [class.editable]. <div class="coolcomponent layout horizontal center" [class.editable]=editable> ..... </div> When using fixture.nativeElement.querySelector('editable');, my e ...

Caution: Potential Unresolved Promise Rejection Detected (ID: 21) - Error: Undefined is not a valid object when trying to evaluate 'res.json'

ERROR Getting an Unhandled Promise Rejection (id: 21): TypeError: undefined is not an object (evaluating 'res.json'). Any suggestions on fixing this issue in my code? I've checked the logs for user and loggeduserobj, and they seem to be cor ...

Exploring the Evolution of jsAjaxForm from jQuery Version 2.1.3 to Version 3.2.1

I'm in the process of upgrading to a higher version of jQuery (3.2.1) and encountering difficulties with updating the ajax file upload functionality using jsAjaxForm from jQuery v2.1.3. Is there a similar function that performs the same role as jaAjax ...

Issues with Contenteditable functionality in JavaScript

My goal is to make a row editable when a button is clicked. $(":button").click(function(){ var tdvar=$(this).parent('tr').find('td'); $.each(tdvar,function(){ $(this).prop('contenteditable',true); }); }); <s ...

Is there a way to turn off linting while utilizing vue-cli serve?

I am currently running my project using vue-cli by executing the following command: vue-cli-service serve --open Is there a way to stop all linting? It seems like it's re-linting every time I save, and it significantly slows down the process of ma ...

Leveraging ngIf and ngFor within choice

Is there a way to combine ngIf and ngFor in a single line of code? Here is the code snippet I am currently using: <option *ngIf="tmpLanguage.id!=languages.id" *ngFor="let tmpLanguage of languages" [ngValue]="tmpLanguage.id"> {{tmpLang ...

From AJAX response to React state attribute, store the JSON data

I have a component where I need to fetch freight values via ajax and store them in the state property of this class. import React, { Component } from 'react'; import Freight from './Freight'; import CreateFreightEntryModal from '. ...

Overuse of jQuery's preventDefault() and stopPropagation() functions

A recent discussion with a coworker revealed some contrasting coding practices, mainly concerning his extensive use of the two aforementioned methods in event handlers. Every event handler he creates follows this same pattern... $('span.whatever&apos ...

How to Pause or Temporarily Halt in Jquery?

Looking to lift the object up, wait 1000ms, and then hide it. I found this snippet of code: $("#test").animate({"top":"-=80px"},1500) .animate({"top":"-=0px"},1000) .animate({"opacity":"0"},500); However, using ".animate({"to ...

Experiencing a [$compile:multidir] error when attempting to implement a multiselect dropdown with Angular.js

I encountered an issue when utilizing a multi-select drop-down list in Angular.js. Error: angularjs.js:107 Error: [$compile:multidir] http://errors.angularjs.org/1.4.6/$compile/multidir?p0=ngDropdownMultiselec…22%20checkboxes%3D%22tr ...

The functionality of the String prototype is operational in web browsers, but it encounters issues

Version: 8.1.0 The prototype I am working with is as follows: String.prototype.toSlug = function () { return (<string>this) .trim() .toLowerCase() .replace(/\s+/g, '-') .replace(/[^\w\-]+/g, '') ...

I'm curious, which redux architecture would you recommend for this specific scenario?

I'm currently developing an application and I'm facing a challenge in implementing Redux effectively in this particular scenario. Unfortunately, due to restrictions at my workplace, normalizing data is not an option. Let's consider the foll ...

Interacting with jQuery mouse events on elements below the dragged image

I'm attempting to create a drag-and-drop feature for images using jQuery. While dragging, I generate a thumbnail image that follows the mouse cursor. However, this is causing issues with detecting mouseenter and mouseleave events on the drop target pa ...

Tips on how to properly format a DateTime String

I need help with formatting a DateTime string retrieved from an API where it is in the format of YYYY-MM-DDTHH:MM:SS +08:00 and I want to change it to DD-MM-YY HH:MM getDataFromApi(res) { this.timestamp = this.timestamp.items[0].timestamp; console ...

Attempting to resolve an error message with the help of JQuery

I need help figuring out how to clear an error icon when a user presses a key. ** EDIT - including the HTML code ** <input class="validate" type="text" data-type="string" id="address" /> <input class=" ...

Vue instance with non-reactive data

I am looking to store an object in Vue that will be accessible throughout the entire instance but does not need to be reactive. Typically, if I wanted it to be reactive, I would use 'data' like this: new Vue({ data: myObject }) However, since ...

Is it possible that the use of excessive React.Fragment could impact performance negatively?

After a recent review of our company's code, I discovered that the performance is not up to par. One common pattern I noticed in the code is something like this: condition ? <SomeComponent /> : <></> I see that Fragments are being u ...

What is the best approach for manipulating live data in localStorage using ReactJS?

I am working on creating a page that dynamically renders data from localStorage in real-time. My goal is to have the UI update instantly when I delete data from localStorage. Currently, my code does not reflect changes in real-time; I have to manually rel ...