1

I've made a sort of drawing application in p5js - I have a multidimensional array called points which consists of shapes, which have x,y coordinates for the points of shapes. So:

shapes[0][0] = [10,10]
shapes[1][3] = [47,98]

etc.

I have a mousePressed function. At the time the mouse is pressed, before the points of these shapes are manipulated, I want to store the original shapes array as undoArr.

Then, as the user drags the mouse, the coordinates in the shapes array are updated. If the user then decides to undo, I have a function keyPressed that I want to be able to populate shapes array with the values from undoArr.

But no matter what I try - it seems that the undo array and the shapes array always have the same values, which is strange because, if I log the state of a coordinate in the shapes array:

function mousePressed() {
  if (!isMousePressed){
    undoArr = [...shapes]; //define undoArr as the current shapes array
    console.log(shapes[0][0]); //outputs 10,41 (for example)

and then log the state on mouseReleased:

function handleMouseReleased(){
    console.log(shapes[0][0]); //outputs 69,122 (for example)

I can verify that they have different values at start and finish. And I can verify from the logs that mousePressed is not accidentally being triggered somehow when it shouldn't, and the same for mouseReleased.

P5js has a draw function, which is constantly repositioning the points of the shapes array based on where the user drags them with their mouse. And in that draw function, I can place a log statement and verify that it fires after mousePressed and before mouseReleased.

However, if I try to store the values of the shapes array on mousePressed, undoArr = [...shapes] and then on keyPressed try to populate the shapes array with the contents of the undoArr, it does nothing - because somehow undoArr always contains the same data as shapes.

Am I copying the array improperly? I've tried instead of the spread undoArr = shapes.slice() but that also didn't work. I've even tried emptying the array first, but nothing seems to work.

A complete gist of the file is available here.

mheavers
  • 29,530
  • 58
  • 194
  • 315

1 Answers1

3

I think what you need here is a deep clone of your multidimensional array. It seems like you are just copying references instead of values.

The spread operator ([...]) does not do a deep clone, so the objects it copies will contain references.

Lodash has a great cloneDeep function: https://lodash.com/docs/4.17.11#cloneDeep

or you could write one of your own.

jsdeveloper
  • 3,945
  • 1
  • 15
  • 14
  • Yes! I just realized that. Wow, been programming a long time and never realized that the nested values in an array would still be references to the original. (This SO post tipped me off: https://stackoverflow.com/questions/7486085/copy-array-by-value). I wrote my own function, but it's nice to know about lodash. Thanks. – mheavers Mar 10 '19 at 00:47
  • happy to help!! – jsdeveloper Mar 10 '19 at 01:01