Guide on generating a fresh array of objects that encompass distinct items, alongside their combined prices and quantities using JavaScript

I am struggling to generate a new array of objects from one that contains duplicates. For instance, here is the console.log output of the current array:

console.log(items);

[{
    _id: 5eb2f7efb5b8fa62bcd7db94,
    workName: 'best item ever',
    workTitle: 'this is the description',
    price: 300,
  },
  <Three objects with this id: 5eb2f7efb5b8fa62bcd7db94>
  {
    _id: 5eb19f3bad682508dc024301,
    workName: 'pack your gift',
    workTitle: 'best packaging for your gift',
    price: 5,
  },
  {
   <Two objects with this id: 5eb19f3bad682508dc024301>
  }]

Is there a way to count the objects, calculate the total price and obtain an array of objects like the following example?

[{
    _id: 5eb2f7efb5b8fa62bcd7db94,
    workName: 'best item ever',
    workTitle: 'this is the description',
    price: 300,
    quantity: 3,
    totalPrice: 900
  },
  {
    _id: 5eb19f3bad682508dc024301,
    workName: 'pack your gift',
    workTitle: 'best packaging for your gift',
    price: 5,
    quantity: 2,
    totalPrice: 10
  }]

Although I've attempted some solutions, I'm unable to figure out how to create the specified new array.

<all variables declaration>

if (cookies) {
        for (let key in cookies) {
            // create new array with works obj
            items.push(value.work = await Work.findById({ _id: cookies[key] }));

            // convert cookies object into an array with the values
            id.push(cookies[key]);
        }

        // return an object where the key is the input array and the value is the number of duplicates
        id.forEach(function (x) { counts[x] = (counts[x] || 0) + 1; });
        let counter = 0;
        for (let i in counts) {
            counter += 1;
            totalPartial.push(items[counter].price * counts[i]);
        };

    }

    //swapping objects
    const newData = Object.keys(counts).reduce(async (obj, key) => {
        obj[counts[key]] = key;
        return obj;
    }, {});
    const total = totalPartial.reduce((partial_sum, a) => partial_sum + a, 0);

Answer №1

If you're looking to find the count and sum of duplicate IDs, you can use the following approach:

var temp = {};
var obj = null;
for(var i=0; i < cookies.length; i++) {
   obj=cookies[i];

   if(!temp[obj._id]) {
      temp[obj._id] = obj;
      temp[obj._id].totalPrice = obj.price;
      temp[obj._id].quantity = 1;
   } else {
      temp[obj._id].totalPrice += obj.price;
      temp[obj._id].quantity++;
   }
}

var result = [];
for (var prop in temp) {
  result.push(temp[prop]);
}

You can simplify the code further, but the main idea remains the same.

For a live example, check out this link

UPDATE

Alternatively, you can also utilize the reduce and filter functions on the array:

cookies.reduce((acc, val) => {
    var o = acc.filter(obj => obj._id == val._id).pop() || {...val, totalPrice:0, quantity: 0};
    o.totalPrice += val.price;
    o.quantity += 1;
    acc.push(o);
    return acc;
},[]).filter((itm, i, a) => i == a.indexOf(itm));

Answer №2

This technique shares similarities with the initial strategy presented by @ThemistoklisBogiatzoglou, but takes a more functional approach.

The concept involves utilizing an object as a data structure to merge items under common keys and then extracting their values from these objects.

const transformedItems = items.reduce((acc, item) => {
  const existingItem = acc[item._id] || { quantity: 0, totalPrice: 0 }
  acc[item._id] = {
    ...item,
    quantity: existingItem.quantity + 1,
    totalPrice: existingItem.totalPrice + item.price
  }
  return acc
}, {})

const finalResults = Object.values(transformedItems)

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

If a user cancels, the radio button in Vue 3 will revert back to

I'm encountering a problem with radio buttons in vue 3. When passing an object from the parent component to the child for data display, I want to set one version as default: <template> <table> ... <tr v-for="(v ...

search for a specific data array in the database with mongoose

In my database, I have stored JSON data that looks like this: [ { "total": 30, "List": [ { //data// } ] } ] I am trying to retrieve the List array while skipping certain items and applying a limit. How can I achieve this u ...

How can I retrieve the index of an element within a 2D array using JavaScript when the array is displayed on a webpage?

https://i.stack.imgur.com/GHx9p.png I am currently working on developing an Othello game board within an HTML page using Angular. The board itself is constructed from a 2D number array which I then display using the <table> tag on the webpage. Below ...

Developing an interactive menu for mobile devices utilizing a combination of JSON, HTML, JavaScript, and CSS

Creating a custom dynamic menu for mobile platforms using HTML, JavaScript, and CSS with a JSON object downloaded from the server. Not relying on libraries like jQuery. I've come across advice stating that "document.write" should not be used in event ...

Express Site with NodeJS

I recently transitioned my express site to a free tier Amazon EC2 Server. While I have managed to get the server up and running, I am facing an issue where the only way I can access the site is through SSH (using Putty). The problem is that once Putty clo ...

Converting JavaScript array within a JSON string into a Golang map

I encountered an issue with an API that returns a JSON where one of the elements is supposed to be an array but is wrapped in quotation marks. This is causing the "encoding/json" package to not recognize that element as an array. When I attempt to access ...

The function canvas.toDataURL() is not recognized - error originating from a node-webGL wrapper

I am currently working on converting client-side volume rendering code in the browser to server-side rendering using pure JavaScript. On the server side, I am utilizing node-webgl. My objective is to send the server's canvas content to the client so ...

Transferring the chosen dropdown value to the following page

I am attempting to transfer the currently selected value from a dropdown to the next page using an HTTP request, so that the selected value is included in the URL of the subsequent page. The form dropdown element appears as follows: <form name="sortby ...

Should developers avoid using jQuery in ReactJS applications?

While working on a ReactJS project (or any other project), I personally prefer using pure JavaScript over jQuery. Lately, I've started questioning whether it's considered bad practice to use jQuery in ReactJS. Back when I was learning ReactJS, I ...

Can anyone recommend any offline editors for HTML, CSS, and JavaScript similar to JSFiddle, jsbin, or codepen?

Is there an alternative to JSFiddle.net that allows users to experiment with Javascript, HTML, and CSS offline in a similar way? ...

Display an error message in Nodejs when the provided username or password is incorrect

I need assistance with handling errors in my post request redirect. app.route('/login') .get(function (req, res) { res.render('formUser', { title: 'Login User', action: 'login', error: 'empty or f ...

Show HTML form elements on the page using jQuery or JavaScript

Is there a jQuery or JS library that can perform the following task: If the user inputs 'x' in A01, then make A01_1 visible. Otherwise, do nothing. <form id="survey"> <fieldset> <label for="A01">A01</label&g ...

Adjustable textarea with automatic height based on content and line breaks

Imagine you have a textarea with text that includes line breaks. If you style it like this: textarea { height: auto; overflow: hidden; resize: none; } Upon loading the page, the textarea will only adjust its height based on the content until it enc ...

Tips for creating an effective planar reflection using Open Graphics Library (OGL) in conjunction with a perspective camera

I'm attempting to create a mirror-like reflection of a WebGL scene on a plane using ogl, similar to how a mirror would behave. I tried implementing a basic version of the three.js reflector but ended up with a distorted image that doesn't accurat ...

Set the array back to its initial value of 1 using jQuery and

After making substantial edits to this question, I find myself in need of a reset button for the code. The current item needs to be reset back to 1 so that I can use it again, but the issue lies in the fact that only the current item is reset while the hig ...

li experiencing a background width problem due to extended text

Check out this code snippet with a problem In the image below, you can see that the background of the li element with more text is larger compared to the others. It's important to note that the <ul> is scrollable. I've experimented with va ...

Guiding motion of a parental container using a button

This seems like a fairly straightforward task, but I'm getting a bit frustrated with it. Is there a way to move an entire div by simply holding down the mouse button on a particular button? let container = document.getElementById('abo ...

Ember.js alternative for Angular's filter for searching through ng-models

Looking for an easy way to implement a search filter similar to Angular? <input type="text" ng-model="resultFilter" placeholder="Search"> <ul> <li ng-repeat="result in results | filter:resultFilter">{{result.name}}</li> </u ...

Tips for correctly mentioning a user while using message.channel.send in discord.js

Looking for guidance on tagging a user properly using message.channel.send in discord.js? Here's the code I'm currently working with: function replaceAll(str, find, replacer) { return str.replace(new RegExp(find, 'g'), replacer) ...

Exploring the art of div transitions and animations using React and Tailwind CSS

I successfully implemented the sidebar to appear upon clicking the hamburger icon with a transition. However, I am now facing the challenge of triggering the transition when the close button is clicked instead. I have attempted using conditional operations ...