Why does this reduce operation seem to be altering the original array?

My goal is to condense the items array to only have one element for "apple" with an updated quantity value. The code snippet below successfully achieves this, but it unexpectedly alters the original items array as well. I'm puzzled by this behavior and would appreciate some insight.

const items = [
    {name: "apples", qty: 1},
    {name: "bananas", qty: 1},
    {name: "apples", qty: 3}
];

const reducedItems = items.reduce(function(newArray, currentItem) {
    const indexForCurrentItem = newArray.findIndex(
        ({name}) => name === currentItem.name
    );
    // Add the item if it doesn't exist in newArray yet
    // If it does, update its quantity property
    indexForCurrentItem === -1
        ? newArray.push(currentItem)
        : newArray[indexForCurrentItem].qty += currentItem.qty;
    return newArray;
}, []);

console.log(reducedItems);
console.log(items);

// The reducedItems array shows: [{name: "apples", qty: 4}, {name: "bananas", qty: 1}]

// However, the items array now looks like:
// [
//     {name: "apples", qty: 4},
//     {name: "bananas", qty: 1},
//     {name: "apples", qty: 1}
// ]

Answer №1

By including objects from the items array into the newArray using newArray.push(currentItem), you are essentially duplicating the same objects with identical references in both arrays. When you proceed to update an object by calling

newArray[indexForCurrentItem].qty += currentItem.qty
, you are altering the object present in both arrays.

To resolve this issue, a simple solution would involve adding copies of objects to the new array.

newArray.push(Object.assign({}, currentItem))

Implementing this adjustment will ensure that the newArray contains shallow duplicates of the objects. Any modifications made to these copies will not impact the originals within the items array.

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

How can I retrieve the attributes of multiple identical components within a webpage?

I've recently delved into learning Vue and decided to create a small application for adding fractions together. I have developed two main components: Fraction.vue and App.vue. The App.vue component contains multiple instances of the Fraction component ...

struggling to implement promises in mongoose operations

Can anyone explain why this promise setup is not functioning as expected? The goal was to remove the documents, add new ones, find them, and then output the data, but it's not displaying anything. var Comp = require("./models/company.js"); var ar ...

Strategies for persisting data in React using local storage to ensure information is retained after page refresh

I am attempting to store searched recipes data in local storage so that when the user refreshes, the data from the last searched recipe will still be available. I have tried saving the recipes data to local storage when a new search request is made and se ...

Vue.js has mysteriously stopped functioning

My Vue.js project suddenly stopped working and I've been trying to figure out the issue for hours with no luck. Here's an overview of my HTML file which includes dependencies and a table displaying data from users. <!DOCTYPE html> <html ...

The error message "Invalid Data Type: Not an Array - google charts" was encountered

I am struggling with an ajax call that I have set up. The issue arises when passing an array from the backend to the frontend. Upon checking the data through an alert on the frontend, everything seems fine. However, Google charts raises an error stating th ...

Is it possible to duplicate a section of an array within the same array

I am currently working on developing a bit reader. My goal is to copy the remaining content of the array to the beginning of the same array before it is fully exhausted, then zero out everything after the copy, and finally fill the remaining space with dat ...

I am not familiar with this HTML element, it's a mystery to me

As I develop a data-recollection view in HTML, I've recognized the necessity of creating something similar to this: To elaborate, it's an image created hastily, with an input where users can enter data. When they click the "+" button, another in ...

Unable to use a button as an event handler in jQuery

As a complete novice, I am on the verge of completing my first website. However, I am facing a roadblock with getting the last button to function properly. It's such a simple task, but for some reason, it just won't cooperate. $( document ).r ...

When using express to serve a static file with sendfile, the route specified is considered as the relative directory rather than its actual location directory

I'm facing an issue with a route in Express router.get('projects/fest', function(req, res, next){ res.sendfile('fest.html', {root: './public'}); }); When accessing localhost:3000/projects/fest, the HTML file is disp ...

Leverage user input to perform various calculations within a component

Struggling to make use of a user-supplied number for multiple computations within a component. The input is successfully utilized in the initial calculation for deckboards, but subsequent calculations such as joists (newArea / 0.45) fail to produce any o ...

Can we apply query projection to a collection that already includes a $elemMatch projection?

I have a question regarding limiting the fields in a matching subdocument array using the $elemMatch projection. It seems like it returns all fields of the subdocuments that match, regardless of any specified query projections. But is there a way to restr ...

Webpack is unable to locate a specific custom JavaScript file

Currently, we are in the process of transitioning from grunt to webpack for our project. Within our project, we have a JS file named boiler that is used to define the core classes which are frequently accessed. __boiler__.js define(function (require) { ...

The equivalent of e.preventDefault() in Java (for Android) is to replace the typed text

I am working on a jQuery/JavaScript function that will replace any text typed in an input field with a specific text. Here is the code snippet: $('input').on('keydown', function(e){ e.preventDefault(); count++; if (count == ...

Tips for integrating custom code into your Angular cli service worker

Although I have successfully generated and configured the service worker using a config file generated by Angular CLI, I am struggling to find documentation on how to add custom code to the ngsw-worker.js file. I want to include functions such as push no ...

Getting a single value from Erlang JSON data: the technique explained

When working with JSON data in Erlang language, I often encounter structures like the following: {"Time":"2020-08-16T15:28:55","BME680":{"Temperature":29.8,"Humidity":55.5,"Pressure":1003.5," ...

Executing a Node.js HTTP GET request is a breeze

I've encountered an issue while attempting to send an HTTP GET request using Node.js. The request to '/path/to/file?query=string' has failed with the error message: read ECONNRESET Any suggestions on how I can resolve this problem? Thank ...

Loop over a generated form with fields using ng-repeat

I am facing an issue where I have an ng-repeat loop and I need to submit the values of input fields within it to a generated form. Using ng-model did not work for me. Is there a way to access the input names inside the form tag? <li ng-repeat="group ...

Send information and showcase it on the following screen using ReactJS

Having recently started using ReactJS for a front-end development project, I encountered a challenge that I need help with. I want to prompt the user for their name using an input field after a question like "What is your name?". Once the user inputs their ...

Having difficulties with Vue components displaying in Laravel's blade.php file

Let me share my current setup with you: This is the main "Welcome.blade.php" file where I have included relevant information as the file is quite lengthy: <div id='app'> <router-view></router-view> </div> <script src ...

The functionality of Jquery ceases to work once a setTimeout function is implemented

I need some help getting a series of functions to be delayed by 2 seconds using setTimeout. For some reason, whenever I try to implement this, the code stops executing altogether. I've double-checked the syntax and everything seems fine because it wor ...