0

I have this class on javascript:

function Node(board,x,y,t){
    this.board = board;
    this.x = x;
    this.y = y;
    this.playerTile = t;
    this.oponentTile = getOponentTile(this.playerTile);
    this.parent = null;
    this.getChildren = getChildren;

};

and I´m using this function which copies the this.board variable (which is an array) to the tempBoard variable using slice()

var getChildren = function() {
        if(this.x==-1 && this.y ==-1){
            var moves = getAllValidMoves(this.board,this.playerTile);
        }
        else{
            var tempBoard = this.board.slice();
            makeMove(tempBoard,this.playerTile,this.x,this.y);
            var moves = getAllValidMoves(tempBoard,this.playerTile);
        }

        var children = [];
        for(var i = 0;i<moves.length;i++){
            var currentMove = moves[i];
            var currentBoard = this.board.slice();
            if(this.x==-1 && this.y ==-1){
                children.push(new Node(currentBoard,currentMove[0],currentMove[1],this.playerTile));
            }
            else{
                makeMove(currentBoard,this.playerTile,this.x,this.y)
                children.push(new Node(currentBoard,currentMove[0],currentMove[1],this.oponentTile));
            }

        }
        return children;
    };

the problem is that after calling makemove() both the tempBoard and the this.board variables are being modified.

Is there any way I can copy an array without it´s reference?

Pablo Estrada
  • 3,182
  • 4
  • 30
  • 74

2 Answers2

1

.slice() makes a shallow copy of the array, not a deep copy.

That means that if you have an array of objects and you use .slice() to make a copy of the array, it gives you a new array that is a first level copy. But the new array points to all the same objects as the first array. You can rearrange the copied array or remove elements from it and that will not affect the first array.

But, if you modify the objects in the array, it is the same objects in both arrays so making a modification to any object in the array (such as changing a property on the object) will be seen in both arrays.

If you want a full copy of the array and it's contents, then you have to make a deep copy which is a bit more complicated and can slightly depend upon what exactly you have in the array.

There are many different ways to make a deep copy. You can read about many of them in these references:

How do I correctly clone a JavaScript object?

Copying an array of objects into another array in javascript (Deep Copy)

Copying array by value in JavaScript

If you are guaranteed not to have any circular references in your array (where one object points to another which points back to it), then the simplest way to make a copy is this:

var tempBoard = JSON.parse(JSON.stringify(this.board));
Community
  • 1
  • 1
jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • Ohh that´s interesting. Then yes, I need a deep copy. My array contains just strings. – Pablo Estrada May 26 '16 at 01:26
  • @PabloEstrada - Are you sure the array contains just strings? Because strings are immutable in Javascript so a `.slice()` would make a copy just fine. Can you show us what is actually in the array and why you think both are getting changed? – jfriend00 May 26 '16 at 01:27
  • I´m sorry, my mistake. I have an array of arrays of strings. Like this `[[' ',' ',' ',' ',' ',' ',' ',' '],[' ',' ',' ',' ',' ',' ',' ',' '],[' ',' ',' ',' ',' ',' ',' ',' '],[' ',' ',' ',' ',' ',' ',' ',' ']]` – Pablo Estrada May 26 '16 at 01:30
  • @PabloEstrada - Then you do need a deep copy. I added several references to methods for making the deep copy and one example. – jfriend00 May 26 '16 at 01:32
  • Thanks for the complete answer :) The stringify worked for me. – Pablo Estrada May 26 '16 at 01:34
1

maybe help

function copy(data){
    var result = JSON.stringify(data);
    return JSON.parse(result);
}
gu mingfeng
  • 1,010
  • 8
  • 10