Reducing an array of objects in Typescript and incrementing a specific attribute

Check out the item array provided below:

const items = [ { itemId: 123, quantity: 1, description: "TEST" }, { itemId: 123, quantity: 1, description: "TEST" }, { itemId: 123, quantity: 1, description: "TEST" }, { itemId: 456, quantity: 1, description: "TESTNEW" }, ];

We need to reduce this collection based on the itemId property and increment the quantity based on the same itemId. The expected output should be:

[ { itemId: 123, quantity: 3, description: "TEST" }, { itemId: 456, quantity: 1, description: "TESTNEW" }, ];

To achieve this, you can utilize Array.reduce in typescript to update the attributes and select only unique itemId values. Below is an example of typescript code used for this purpose:

    export interface MiniBagItem {
  name?: string;
  sku?: string;
  quantity?: number;
}
const item1: MiniBagItem = { name: "test", sku: "123", quantity: 1 };
const item2: MiniBagItem = { name: "test", sku: "123", quantity: 1 };
const item3: MiniBagItem = { name: "testNew", sku: "456", quantity: 1 };
const miniBagItems: MiniBagItem[] = [];
miniBagItems.push(item1, item2, item3);
//start reduce
let seenMap = new Map();
miniBagItems.reduce<MiniBagItem>((acc: MiniBagItem[], obj, index) => {
  let seen = seenMap.get(obj.sku);
  // eslint-disable-next-line @typescript-eslint/no-unused-expressions
  seen !== undefined
    ? acc[seen].quantity++
    : (seenMap.set(obj.sku, index), acc.push(obj));
  acc.push(obj);
  return acc;
}, []);

//console.log(newItems);
export {};

https://i.sstatic.net/cW8Ki.png

Answer №1

You have the option to utilize array#reduce for looping through each object in the items array. The accumulator (acc) is utilized to maintain a new array of objects with the quantity property being specified.

const items = [ { itemId: 123, quantity: 1, description: "TEST" }, { itemId: 123, quantity: 1, description: "TEST" }, { itemId: 123, quantity: 1, description: "TEST" }, { itemId: 456, quantity: 1, description: "TESTNEW" }, ];

let seenMap = new Map();
const newItems = items.reduce((acc, obj, index) => {
  let seen = seenMap.get(obj.itemId);
  seen !== undefined ? acc[seen].quantity++ : (seenMap.set(obj.itemId, index), acc.push(obj));
  return acc;
}, []);

console.log(newItems);

Note: Instead of using an array, I opted for a Map() for the seenMap variable to ensure the time complexity remains at O(N).

The typescript snippet you need:

export interface MiniBagItem {
  name?: string;
  sku?: string;
  quantity?: number;
}
const item1: MiniBagItem = { name: "test", sku: "123", quantity: 1 };
const item2: MiniBagItem = { name: "test", sku: "123", quantity: 1 };
const item3: MiniBagItem = { name: "testNew", sku: "456", quantity: 1 };
const miniBagItems: MiniBagItem[] = [];
miniBagItems.push(item1, item2, item3);

//start reduce
let seenMap: Map<string, number> = new Map();
miniBagItems.reduce<MiniBagItem[]>((acc: MiniBagItem[], obj, index) => {
  let seen = seenMap.get(obj.sku);
  // eslint-disable-next-line @typescript-eslint/no-unused-expressions
  seen !== undefined
    ? acc[seen].quantity++
    : (seenMap.set(obj.sku, index), acc.push(obj));

  acc.push(obj);
  return acc;
}, []);

//console.log(newItems);
export {};

Answer №2

Apply this method to filter the items based on one of their properties:

const products = [
  {
    productId: 987,
    quantity: 2,
    description: 'EXAMPLE'
  },
  {
    productId: 987,
    quantity: 2,
    description: 'EXAMPLE'
  },
  {
    productId: 987,
    quantity: 2,
    description: 'EXAMPLE'
  },
  {
    productId: 654,
    quantity: 1,
    description: 'NEWEXAMPLE'
  }
];

const result = products.filter((item, index, array) => array.findIndex((element) => element.productId === item.productId) === index);
console.log(result);

Answer №3

In dealing with relatively simple objects, a straightforward method is to use the deep-equals approach by leveraging JSON.stringify() and JSON.parse().

An Illustrative Example

const items = [
  { itemId: 123, quantity: 1, description: "TEST", },
  { itemId: 123, quantity: 1, description: "TEST", },
  { itemId: 123, quantity: 1, description: "TEST", },
  { itemId: 456, quantity: 1, description: "TESTNEW", },
];

const flatItems = items.map(item => JSON.stringify(item));
let reduced = [];

flatItems.forEach((flatItem) => {
  if (!reduced.includes(flatItem)) {
    reduced.push(flatItem);
  }
})

reduced = reduced.map(flatReduced => JSON.parse(flatReduced));

// For displaying the output in HTML
document.querySelector('pre code').textContent = JSON.stringify(reduced, null, 2); hljs.highlightElement(document.querySelector('pre code'))
<link rel="stylesheet"
      href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/ocean.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.2.0/highlight.min.js"></script>

<pre><code class="language-json hljs"></code></pre>

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

Display a list containing values retrieved from a separate list

Apologies if the question comes across a bit awkwardly. Here is what I am attempting to achieve: I currently have a list. standardpizzalist = ["1. Supreme", "2. Godfather", "3. Meatlovers", "4. Capricosa", "5. BBQ Chicken", "6. Prawn Delight", "7. Basil ...

sending a collection of JSON objects from PHP to an Android device

I am attempting to send an array of data from PHP to Android using a JSON object. However, I keep encountering a "Parse error: syntax error". Any assistance would be greatly appreciated. Thank you. //db details $dbhost="localhost"; $dbuser="root"; $dbpas ...

Breaking apart a string array without relying on the split(String regex) function

I have a String array that contains the "_" character in each element, and I need to remove these characters. While I could easily accomplish this task using the split(String regex) method, I am hesitant as I plan to use this code in J2ME later on. I att ...

Implementation of the Comparator Interface within a nested class

Although I am fairly new to stackoverflow.com, I have often relied on it to find solutions whenever I encountered an issue. This time, however, I couldn't find any results related to my current problem, which is why I am reaching out for help here :) ...

Error in TypeScript Compiler: When using @types/d3-tip, it is not possible to call an expression that does not have a call

Seeking help to understand an error I encountered, I have read all similar questions but found no solution. My understanding of TypeScript is still growing. I am attempting to integrate the d3-tip module with d3. After installing @types/d3 and @types/d3-t ...

Incorporate the leaflet Draw feature into your Angular 2 application

I am a newcomer to Angular2, created using Cli. While I successfully imported Leaflet into my Angular2 project without any Angular2 directives, I am struggling to do the same with the Leaflet Draw extension. I haven't been able to make Draw work. In e ...

Angular 2 search feature failing to accurately filter results based on user-provided input string

How can I implement a filter for the users list based on specific details? The users list is populated from form data and displayed in the view using *ngFor. I attempted to create a custom pipe to filter the userslist based on a search query inputted in a ...

Using PHP's Foreach Loop to Display Every Emoji

PHP 7 now has improved support for Emojis, but there is no pre-packaged set or library of emojis to reference from. Currently, I have to manually search for the UNICODE of the emoji I want at . Is there a more efficient way to retrieve all the latest emoj ...

Loop through an array of JavaScript objects, compare a specific value within each object with all others to ensure uniqueness, and then add the unique objects to a new array

What is a efficient method to iterate through a JavaScript array of objects, and within each object, verify the uniqueness of a specific value compared to all others before adding it to a new array. Here is the sample array of objects: const weatherArray ...

Iteration in Angular using ForEach Statement

Can anyone help me with executing a For loop synchronously in Angular 5? The code I have so far doesn't wait until ExcecuteAsyncCode is completed. let items = new Array<Item>(); for (let i = 0; i <= 10000; i += 1) { this.ExcecuteAsyncC ...

I am facing an issue with updating the mat-table after pushing values to a

I have a uniqueFormGroup with UniqueFormArray and a special-table that displays the array. When I add new uniqueFormGroup to UniqueFormArray, the special-table doesn't add new row. I was attempting to implement trackBy, but I am unsure of where (and ...

I encountered a problem after upgrading to Angular 10 that is preventing me from reading property '0' because it is undefined

Recently, I updated my Angular application from version 8 to version 10. However, when I try to run ng serve, I encounter the following error message: ERROR in Cannot read property '0' of undefined This error seems quite obscure and difficult to ...

There seems to be an issue with a potentially null object in an Angular project while trying to view a PDF file

IDENTIFY THE ERROR: printContents = document.getElementById('print').innerHTML.toString(); ON LINE 4: print(): void { let printContents!: string; let popupWin!: any; printContents = document.getElementById('print').innerHTM ...

Arranging a connected list of elements

Background: I have a LinkedList class that organizes and inserts nodes automatically in the correct order. This linked list data structure represents RAM, with the array holding the nodes/elements and the pointers - head, tail, next, and prev representing ...

Customize nestjs/crud response

For this particular project, I am utilizing the Nest framework along with the nestjs/crud library. Unfortunately, I have encountered an issue where I am unable to override the createOneBase function in order to return a personalized response for a person e ...

Waiting for the response to come by subscribing in Angular

I am encountering an issue while trying to subscribe to an Observable and assign data from the response. The problem is that my code does not wait for the response before executing the console.log(this.newIds) line, resulting in an empty value being logg ...

Using TypeScript to Implement Content Security Policy Nonce

I encountered an issue with my TypeScript Express project while attempting to implement a CSP Nonce using Helmet. app.use(helmet.contentSecurityPolicy({ useDefaults: true, directives: { scriptSrc: ["'self'", (req, res) = ...

When the value of a react state is used as the true value in a ternary operator in Types

Attempting to implement sorting on a table is resulting in the following error: (property) direction?: "asc" | "desc" No overload matches this call. Overload 1 of 3, '(props: { href: string; } & { active?: boolean; direction? ...

The reason why Class-validator doesn't handle fields that lack a decorator in Nest js

After creating a DTO for my endpoint, I encountered an issue where the class-validator stops checking a field if it doesn't have a decorator assigned to it. Even though I need the field to be mandatory and checked, it gets skipped. DTO: import {IsNum ...

Are there any issues with the onClick function not being detected in React?

I am currently working on a project using NextJs and TypeScript, and I have encountered some strange issues with the onClick function. It appears that the function is not being recognized within my component. "use client"; import styles from &quo ...