4

Okay so I am trying to make an AI for a game called notakto. That much isn't relevant however, in order to make the search algorithm that I do I need to duplicate array. So I have a global array called board which looks like this [[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0]] where all of the 0s are different numbers. To copy this I have the following line. var newboard=board.slice(). Problem is when I run a line of code like newboard[0][0]=1 it changes also acts as if I have run the following board[0][0]=1.

6
  • 3
    You have to make a copy of each of the nested arrays too. Commented Mar 28, 2016 at 21:28
  • .slice() makes a copy of the array it's given, but it doesn't work recursively. Commented Mar 28, 2016 at 21:31
  • If you're using jQuery, you can get a deep copy with $.extend. Commented Mar 28, 2016 at 21:32
  • 2
    There's always the old var copy = JSON.parse(JSON.stringify(board)); trick Commented Mar 28, 2016 at 21:35
  • slice() make only shallow copy. See jQuery.extend() Commented Mar 28, 2016 at 21:35

4 Answers 4

1

You copy your array, but the inner arrays are not copied. This is a litte bit hacky but it works:

var newboard = JSON.parse(JSON.stringify(board));

In this context it will work, but if your object has any functions these are lost through stringify. Moreover it could make some trouble with Data objects which are stored inside the object.

Sign up to request clarification or add additional context in comments.

2 Comments

You might want to explain the limitations of this approach so that others are not blindly copying this.
@FelixKling Thanks for your advice. I edited the post to mention some limitations I know.
0

javascript is always reference based. if you want to make a duplicate copy, please do deep object copy instead of sallow copy. In angular, angular.copy() will perform deep copy.

var newboard=angular.copy(board.slice());

2 Comments

There is no angular tag on this question.
that is for just example to understand the concept.
0

It's because nested arrays are shallow-copied by reference. You can use a recursive function like this to deep-copy a multidimensional array such as the one you have above, making sure that each nested array is copied by value:

function copyMultidimensionalArray(array) {
    var r = array.slice(0);
    for (var i = 0, l = r.length; i < l; ++i) {
         if (Array.isArray(r[i])) {
             r[i] = copyMultidimensionalArray(r[i]);
         }
    }
    return r;
}

/* example */

var board = [[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0]],
    anotherBoard = copyMultidimensionalArray(board);

anotherBoard[0][0] = 99;

document.write([
    "board[0][0] ===",
    board[0][0],
    "&& anotherBoard[0][0] ===",
    anotherBoard[0][0]
].join(" "));

Comments

0

You can also use board.map(function(cv){ return cv.slice();}) to copy the board:

var board = [[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0]];

var board2 = board.map(function(cv){ return cv.slice();});

board2[0][0] = 1;

console.log(board);
console.log(board2);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.