-1

I'm trying to write a function that picks a random entry from a multidimensional array (myArray), saves it to a new variable (myTempArray) and updates the first entry with an id number (counter).

When I change the value of mytempArray[0][0][0] it updates the equivalent value in myArray as well. I don't want these values to change.

How do I stop this from happening? Is slice the wrong method to use? If so, how do I duplicate the original array entry so I can modify it and use elsewhere? Code is below:

var myArray = [
[[0, "Description 1", 0, 0, 1, 6, 0, 0, 0, true, 0]],
[[0, "Description 2", 0, 0, 1, 6, 0, 0, 0, true, 0]],
[[0, "Description 3", 0, 0, 1, 6, 0, 0, 0, true, 0]],
];

function randomNumber (min, max) {
return Math.floor((Math.random() * max) + min);
};

counter = 1;

function myfunction(){

myrand = randomNumber(0,myArray.length-1); 
mytempArray = myArray.slice(myrand,myrand+1);
mytempArray[0][0][0] = counter;
counter++;
};

myfunction();
TimmyL
  • 11
  • 3

1 Answers1

0

Remember that slice only works at one level in your structure. If you want a deep copy, you have to implement that yourself.

function myfunction() {
    var myrand = randomNumber(0, myArray.length - 1);
    var mytempArray = myArray.slice(myrand, myrand + 1); // <== Only copies one level
    mytempArray[0] = mytempArray[0].slice();             // <== Copy the next
    mytempArray[0][0] = mytempArray[0][0].slice();       // <== And the next
    mytempArray[0][0][0] = counter;
    // Presumably do something with `mytempArray` or return it
    counter++;
}

See below for a couple of other changes I made in there.


A couple of side notes:

  • Unless you're declaring myrand and mytempArray somewhere you haven't shown, your code is falling prey to The Horror of Implicit Globals*. Be sure to declare your variables.
  • There's no need for a ; at the end of a function declaration (as opposed to a function expression). ; is a statement terminator. Declarations aren't statements.

* (that's a post on my anemic little blog)

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Assuming that the data is valid JSON, `var deepCopy = JSON.parse(JSON.stringify(oldArray));`. – Jared Smith Dec 30 '17 at 16:58
  • @JaredSmith: I believe strongly that using `stringify`+`parse` to copy data is wrong on several levels. :-) – T.J. Crowder Dec 30 '17 at 17:00
  • Well, the general-purpose alternative is to recursively copy the data structure. Which in JavaScript means either trampolining or keeping an explicit stack to avoid running out of memory. Or you could write a million one-off versions for specific data structures with all the duplication and bug-potential that implies. I don't think it's going to be 'right' no matter which way you slice it (pun intended). – Jared Smith Dec 30 '17 at 17:09
  • thanks @T.J.Crowder that worked! – TimmyL Dec 30 '17 at 17:16