Issue with mutations when passing matrix arguement

EDIT: If you would like a simplified version of this issue, I replicated it here: https://replit.com/@Michael_Nicol/Issue#index.js

You can see I try to create a newGrid with the first cell becoming “TEST” but it mutates my first grid despite using spread operator.

This would remove any of the confusion that may come with look through my code.


Hello,

I am currently working on a maze generating and solving algorithm. It can be found at:

I know it is over 350 lines of code, but all of it works besides one issue I have identified.

From line 0 to 321 I declare various functions in order to help create the maze, add random barriers, and then solve it. I put various comments in these functions to explain how it works.

The way it works is found in this video: The Lightning Algorithm - Numberphile - YouTube

I basically took the concept and wrote it myself in JavaScript. It isn’t completely done and is only up to the number mapping part.

From lines 322 to 352 I run these functions in order. The grid is stored in a global variable so and I change it as I go along with the various functions.

On line 348 I run the number mapping function (mapDistance) in order to map the cells distance from the starting point and assign the output to a new grid varaible.

Diagram from the YT video that demonstrates this:

 var distanceGrid = mapDistance([...grid], startPoints[startIndex], barrier)

The issue is that my global grid variable is being mutated despite using the spread operator in the argument. Notice on line 349 I use a console command to show grid’s value after the function is run. It should not have any numbers inside of it, but it does. After that I display the value of the new distanceGrid, which should be the only grid with numbers in it.

console.log(displayGrid(distanceGrid[1],barrier))

I want to pass grid into mapDistance without mutating it. This is because in the future (as seen on line 363) I want to make it so my mapDistance is re-run until it finds a starting point that works. This is because my code currently only tries a single starting point.

If grid is mutated and numbers are stored in the global variable, it will mess with the re-run process. I tried using the spread operator to copy in place, but for some reason it does not work.


NOTE: if you try to run it and receive a error with no starting or ending points:

Just keep re-running it until you get one that does not error out. I put the rates of barriers spawning on purpose to make sure I can test the program’s ability to figure out if a maze is not solveable.

Note: Spread syntax effectively goes one level deep while copying an array. Therefore, it may be unsuitable for copying multidimensional arrays …

Source: Spread syntax (...) - JavaScript | MDN

Since you have a two-dimensional array, the spread operator does not work as you expect. A simple solution would be to create a cloneGrid function that ‘deep clones’ the grid:

const cloneGrid = (grid) => {
  let clone = [];
  for (const row of grid) {
    clone.push([...row]);
  }
  return clone;
}

Then you can just pass cloneGrid(grid) instead of [...grid] wherever you need it.

1 Like

I tried implementing this on a test repl.it and still am having issues. Did I use it in the correct way?

No, you use gridClone.push(row). And since row is an array, it will still use the same reference for the row in the original and the copy (i.e. the copy is still only one level deep). You can use gridClone.push([...row]) to also deep copy the next level.

1 Like

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.