Categorize array elements based on nested object property and combine them

My data structure includes an array as shown below:

BasketDish

[
  {
    id: string;
    quantity: number;
    Dish: AsyncItem<Dish | undefined>;
    basketID: string;
    createdAt?: string | null;
    updatedAt?: string | null;
    basketDishDishId?: string | null;
  }
]

Dish

[
  {
    id: string;
    name: string;
    price: number;
  },
  {
    id: string;
    name: string;
    price: number;
  }
]

I am looking to group the array by Dish.id and then create a new array that calculates the total quantity and price for each dish

Starting from:

[
  {
    id: 1,
    name: BBQ Burger,
    price: 17
  },
  {
    id: 2,
    name: CheeseBurger,
    price: 15
  },
  {
    id: 2,
    name: CheeseBurger,
    price: 15
  },
]

The desired result is:

[
  {
    id: 1,
    name: BBQ Burger,
    price: 17,
    total: 17,
    quantity: 1
  },
  {
    id: 2,
    name: CheeseBurger,
    price: 15,
    total: 30,
    quantity: 2
  },
]

I have attempted various methods like using groupBy and merge, but I haven't been successful

UPDATE

Thanks @BioStunt

I just needed to modify your solution to group by Dish.id instead of id

/**
 * Merge Dishes with same id
 */
const groupedItems = chain(basketDishes)
  /** group items by key "id" */
  .groupBy(a => a.Dish?.id)
  /** convert grouped items */
  .map((items, id) => ({
    id: id,
    dishId: items[0]?.Dish?.id,
    name: items[0].Dish?.name,
    quantity: items.length,
    total: items.reduce((acc, item) => acc + item.Dish?.price!, 0),
  }))
  /** get result of chain */
  .value();

Answer №1

If you've got a basic array of basket items and want to merge them using lodash, try using chain and groupBy methods. For example, let's say your base item array is as follows:

const basket = [ 
  { id: 1, name: 'BBQ Burger', price: 17 }, 
  { id: 2, name: 'CheeseBurger', price: 15 }, 
  { id: 2, name: 'CheeseBurger', price: 15 }, 
];

You can merge this data by applying the following code snippet:

const groupedItems = _.chain(basket)
  .groupBy('id')
  .map((items, id) => ({
    id: Number(id),
    name: items[0].name,
    quantity: items.length,
    total: items.reduce((acc, item) => acc + item.price, 0)
  }))
  .value();

The console output will display the merged items like so:

groupedItems.forEach((item) => 
  console.log(`${item.quantity} * ${item.name} | ${item.total}`)
);

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

Utilizing GraphicsMagick with Node.js to Extract Page Frames from Multi-Page TIF Files

I am currently working with a JavaScript script that can successfully convert a single page TIF file to JPEG. However, I am facing difficulties in determining whether "GraphicsMagick For Node" (https://github.com/aheckmann/gm) has the capability to extra ...

manipulating the flow of callback functions using jQuery

When the function socialbookmarksTableData(data) is called by another function, it generates the content of a table using data in JSON format. Inside this function, two other functions are called which use getJSON and POST methods to retrieve some data. ...

The value of 'useFonts' cannot be changed as it is a read-only property in expo-fonts

Struggling with 'useFonts' being read-only and unable to assign In my Expo project using React Native (TypeScript), I encounter the issue of trying to import a .ttf font file. My attempt was to create a custom hook called "useFont" to pre-load ...

Transfer dropzone files exclusively upon pressing a button

Greetings to all! I am a newcomer here, and I am also new to jquery. I came across an article that explains how to upload multiple files at once on a website using Dropzone.js in ASP.NET Webforms. You can find the article here. Upon implementing the code ...

Binding Vue data with Firestore

I am looking to extract information from a firestore database and link it to the vue data. To retrieve data from firestore, I use the following method within the created lifecycle hook: created(){ console.log(firebase.auth().currentUser); const docRef ...

How to retrieve a nested array element in JavaScript

Here is the Pastebin link of the index.html file for reference: http://pastebin.com/g8WpX6Wn (The file contains broken image links and no CSS styling). If you would like to access the entire project, you can download the zip file. I am currently working ...

"Utilize Typescript to create a function within a nested object structure

I have a scenario where I am trying to access the foo variable inside the function a of the test object. class bar { private foo: string = "foobar"; constructor() { /* ... Implementation ... */ } fncA(): this { // ... implementation ...

What is the best way to access a variable's value from outside a promise?

I encountered an issue while trying to assign a value to a variable outside of a promise. Despite defining the variable outside the promise, it is showing up as undefined when I check its value. Could someone assist me with this problem by reviewing my co ...

Every time I attempt to reuse my components, they keep piling up on top of each other

I'm facing an issue where I need to reuse components I've created multiple times while rendering dynamic content. However, when I attempt to render them, they end up stacking on top of each other in the same position. Each time I render ...

Discover the method for invoking a Javascript function within a Leaflet popup using HTML

Upon clicking on a marker on the leaflet map, I aim to trigger a popup box that contains five elements: Title Description Image Button (Next Image) Button (Previous Image) To achieve this, I attempted to include a custom popup for each feature ...

Is add1 missing from the DOM? Learn how to include it

Having an issue with Java-Script and an HTML form. The scenario is that there's a main form with an "Add" button, which when clicked should display a second form. Next to the second form is another button labeled "Add1," which ideally should trigger ...

Please insert a decimal point and thousand separator into the text field

I'm trying to incorporate thousand separators and decimal points into my text box. Additionally, I have implemented the following directive: .directive('format', function ($filter) { 'use strict'; return { requir ...

Utilizing the JavaScript map method to structure API response data

Here is the JSON data I have: { "result": [{ "name": "a", "value": 20, "max": 100, "sale_value": [{ "no": 1, "name": "aaaaa", "price": 200 }, { "no": 2, ...

Updates made to ajax-cart.js are not being reflected in Prestashop

I have recently modified the code in themes/default-bootstrap/js/modules/blockcart/ajax-cart.js. $(document).off('click', '#add_to_cart button').on('click', '#add_to_cart button', function(e){ e.preventD ...

Even after applying trim() function, PHP's return statement still adds spaces unnecessarily

My function is supposed to return a boolean, but for some reason, it is adding spaces at the beginning of the string. Even after using trim(), the spaces persist. What could be causing this unexpected behavior? PHP function checkFile($v){ $result = is_ ...

How to add texture to a three.js element

I'm struggling to properly apply a texture to an object I exported. Here is the code I have: var loader = new THREE.ObjectLoader(); var texture = THREE.ImageUtils.loadTexture('models/mountain/mountain.png'); loader.load("models/mountain/mo ...

Chrome crashing due to toDataURL

Recently, I have been working on a Tile Renderer for three.js and so far, everything appears to be functioning correctly. The process is quite simple: a) It creates multiple cameras, b) Renders the scene using each camera c) Generates a 'toDataURL&a ...

Personalized information boxes for particular data points within highcharts

When hovering over specific points, I want to display unique warnings or explanations in the tooltip. I have included custom text like 'WARNING' and 'WARNING 2' within the series data but am struggling to retrieve that data for each too ...

Looking for the location of a matching brace in a dataset?

As a newbie in the world of coding, I have embarked on learning about NodeJs file system module. Currently, my focus is on handling a large data file stored as a string. The challenge that I am facing is with locating the matching close brace and its pos ...

When I engage with the input field, it ceases to be in focus

Here is the code I've been working on: https://github.com/Michael-Liendo/url-shortener/blob/main/src/pages/index.js If you want to see the issue for yourself, check it out at: ...