Modifying the value of an item within a two-dimensional array

I've encountered a perplexing issue while working with a two-dimensional array named "grid" that holds objects known as "squares". In this scenario, each square simply keeps track of how many times it has been selected (clicked).

After initializing the grid, the structure appears as follows...

this.grid = [   
    [{"selected":0},{"selected":0},{"selected":0}]
    ,[{"selected":0},{"selected":0},{"selected":0}]
    ,[{"selected":0},{"selected":0},{"selected":0}]  
];

The problem arises when attempting to increment the "selected" value of a single object in the grid using this.grid[x][y].selected += 1;. Instead of updating only one object, all values in the corresponding row get incremented, resulting in...

[   [{"selected":0},{"selected":1},{"selected":0}]
    ,[{"selected":0},{"selected":1},{"selected":0}]
    ,[{"selected":0},{"selected":1},{"selected":0}]  ]

This unintended behavior is not what I intended. :(

The root cause seems to lie within the process of creating the grid's array structure, as manipulating individual objects works when hard-coded. What could be causing this issue and how can it be resolved?

Below is the JavaScript code snippet...

function GridClass () {
    this.$grid = $('.grid');
    this.grid = [[]]; 

    this.createGrid = function () { // Suspected source of the issue
        var baseSize = 3;
        this.grid = [];
        var blankYArray = [];
        for (var y = 0; y < baseSize; y++) {
            blankYArray.push({
                "selected" : 0
            });
        }
        for (var x = 0; x < baseSize; x++) {
            this.grid.push(blankYArray);
        }
    }

    this.selectSquare = function (x, y) {
        this.grid[x][y].selected += 1;
        this.drawGrid();
    }

    this.drawGrid = function () {
        var h = "", rowClass = "";
        var xLen = this.grid.length;
        var yLen = this.grid[0].length;
        for (var y = 0; y < yLen; y++) {
            for (var x = 0; x < xLen; x++) {
                var g = this.grid[x][y];
                h += '<div class="' + rowClass 
                + ' alt' + g.selected + '"'
                + ' data-x="' + x + '"'
                + ' data-y="' + y + '">'
                + x + "," + y + '</div>';
            }
            h += '<br />';
        }
        this.$grid.html(h);
    }

    this.createGrid();
    this.drawGrid();
}
grid = new GridClass();

grid.$grid.on("click", "div", function(e){ // Click event for each square
    var $thisSquare = $(this);
    var x = $thisSquare.data("x");
    var y = $thisSquare.data("y");
    grid.selectSquare(x, y);
});

A simple HTML layout:

<div id="gridFrame"><div class="grid"></div></div>

To view the complete setup along with CSS styles, visit the jsfiddle link provided: http://jsfiddle.net/luken/fu4yW/

Answer №1

Following Sergio's advice, consider creating a new array during each iteration of the loop...

for (var x = 0; x < baseSize; x++) {
        var emptyArray = [];

        for (var y = 0; y < baseSize; y++) {
            emptyArray.push({
                "selected" : 0
            });
        }

            this.grid.push(emptyArray);
        }

Check out the fiddle here: http://jsfiddle.net/larsmaultsby/fu4yW/8/

Answer №2

Make sure to modify your code as you are currently adding the same array multiple times to the grid. Consider the following updated version:

for (var x = 0; x < baseSize; x++) {
  this.grid.push(blankYArray.slice(0));
}

By utilizing the slice method, you can obtain a new sub-array of the original one. Using slice(0) will generate a fresh array with identical values.

Correction

Unfortunately, this approach is not suitable for arrays containing objects. Since the array holds objects, the slice method will produce a reference to a new array. However, it will still maintain references to the initial array objects. To rectify this issue, create a new array in each iteration with distinct objects as illustrated in user1133128's response:

for (var x = 0; x < baseSize; x++) {
    var blankYArray = [];
    for (var y = 0; y < baseSize; y++) {
        blankYArray.push({
            "selected" : 0
        });
    }
    this.grid.push(blankYArray);
}

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

Client-side rendering for NextJS server components is also supported

I am currently working with Material UI v5.11.16 in a nextjs environment using v13.3.0. I followed the official documentation setup for my nextjs project which can be found here. So far, I have successfully integrated Material UI components without having ...

Strategies for effectively engaging with dynamically created forms amidst a multitude of other forms on a webpage

One of the challenges I face is dealing with a page that has multiple forms dynamically generated based on user input. Each form contains two sets of radio buttons, with the second set being disabled by default and enabled based on the users' selectio ...

The functionality of the Bootstrap tabbed pane is not functioning correctly

I am currently in the process of creating a modal tabbed pane in bootstrap following the instructions provided in this guide. You can view the code and functionality on this fiddle. $(document).on("click","#tabs a",function(event) { alert("!!!"); ...

What is the most efficient way to apply a class to the post div every 4 seconds using jQuery?

What is the most effective method to dynamically add a class to each div element with a class of "post" every 4 seconds using jQuery? <div class="34 post"> <img width="311" height="417" src="#" class="#" alt="newspapers" /> <h2><a hre ...

Is it possible for Node.js to execute individual database operations within a single function atomically?

As I delve into writing database queries that operate on node js, a puzzling thought has been lingering in my mind. There seems to be a misunderstanding causing confusion. If node is operating in a single-threaded capacity, then it follows that all functi ...

Securing your Node.js connect-rest REST API with OAuth: A comprehensive guide

After conducting an extensive search on Google for examples related to my query, I was left empty-handed due to the generic name of the "connect-rest" package. My objective is to secure a server side API that I have built using the Node module "connect-re ...

The button works properly in JSFiddle, however, it is not able to clear the ordered list in the

DEMO Creating a script that captures mouse click coordinates and appends them to a list. The functionality works, except for an issue with the clear button not working properly. After making corrections in jsfiddle, the script functions correctly. Howeve ...

The initial click may not gather all the information, but the subsequent click will capture all necessary data

Issue with button logging on second click instead of first, skipping object iteration function. I attempted using promises and async await on functions to solve this issue, but without success. // Button Code const btn = document.querySelector("button") ...

My Tailwind CSS toggle button disappears in dark mode, why is that happening?

<button aria-label="Toggle Dark Mode" type="button" className="lg:inline-flex lg:w-40 md:w-screen p-3 h-12 w-12 order-2 md:order-3" onClick={() => setTheme(theme === 'dark' ? &ap ...

Discover the security vulnerabilities in Node.js when using VS Code with FREECODECAMP's React app

As a beginner in using VS code, I attempted to work on a project for FREECODECAMP. This project involved creating a random quote machine, marking my first time coding a react project. While following a YouTube tutorial and making progress towards functiona ...

Avoid altering the Vuex store state directly without using mutation handlers in VueJS

I am currently working on developing a listenAuth function that monitors the "onAuthStateChanged" event in firebase to inform the vuex store whenever a user logs in or out. From what I can gather, I am only updating state.authData using the mutation handle ...

What is the method for including a placeholder with sequential numbering?

When I click on the "Add String" button, it clones the first table row with an input in the table and adds it to the table. I also need to add a +1 number in the placeholder of the copied element. How can I determine the last placeholder before copying and ...

What is preventing me from installing React and uninstalling create-react-app from my system?

I've exhausted all my options but still can't seem to figure out how to install ReactJS on my system. Every time I complete the installation process, I encounter this error message: A template was not provided. This is likely because you' ...

Having trouble with Vee-validate Basic example - undefined errors issue

I've been struggling to get a basic form validation page working with vee-validate. Something seems to be going wrong, but I can't pinpoint the exact issue. Why am I seeing the error: errors not defined. <!DOCTYPE html> <html> < ...

Eliminating the dependency on Angular $http in a custom JavaScript library

Is there a way to develop a versatile JavaScript library that can be utilized across different frameworks, while still being able to leverage Angular's $http service when necessary? Would it be feasible to incorporate jQuery as a fallback for other fr ...

Enhancing Filtering Capabilities with Multiple ng-Model in AngularJS

I am facing an issue with filtering a form based on user input in a text box or selection from a dropdown list. The text box filter works fine individually, but when I try to combine it with the dropdown list selection, neither filter seems to work. Below ...

AngularJS - Ensuring the <script> tag is included only after all directives have been rendered

Forgive me if this question has been asked before. I've spent quite some time looking for a solution to no avail. I'm in the process of converting an existing application, which relies heavily on jQuery, to utilize AngularJS. However, I've ...

Is there a way for the React select component to adjust its width automatically based on the label size?

After defining a React select component, it looks like this: <FormControl> <InputLabel id="demo-simple-select-label">Age</InputLabel> <Select labelId="demo-simple-select-label" id=&quo ...

I encountered an issue in node.js where I was unable to delete a folder after renaming a zip

When attempting to rename an uploaded file using the code below: fs.rename('xxxxx','xxxxx',function(err) { }); I encountered an issue within the callback function. I attempted to remove a folder using the following code: fs.rename(& ...

jQuery does not support iterating over JavaScript objects

Here is the code snippet I am working with: $(obj).each(function(i, prop) { tr.append('<td>'+ i +'</td>' + '<td>'+ prop +'</td>'); }); Intriguingly, the data in $(obj) appears as: Obje ...