Reputation: 59
const queenThreat = function (board) {
let collision = false;
let newBoard = board.slice(0);
// Horizontal
let horizontal = newBoard[whiteQueen[0]];
horizontal.splice(5, 1, 0);
collision = horizontal.includes(1)
return board;
// Original array
[ [ 0, 0, 0, 0, 0, 1, 0, 0 ],
[ 0, 0, 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 1, 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, 0, 0 ],
[ 0, 0, 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0, 0, 0 ] ]
// Original array after above code despite cloning the array and only accessing the cloned array
[ [ 0, 0, 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 1, 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, 0, 0 ],
[ 0, 0, 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0, 0, 0 ] ]
I've cloned my array using slice(), accessed it instead of the original array under //Horizontal, and yet when I return the original array it's STILL modified. What am I doing wrong? I've tried every way to create a clone of the array and they all somehow modify the original despite never accessing it.
Upvotes: 0
Views: 1180
Reputation: 11
In 2024, you can use structuredClone, majorly for arrays and objects. It provides a deep clone of the given value. For shallow copy you can use the above answer given by @xynon - https://stackoverflow.com/a/60460458/11410210, which I would suggest to use as per requirement.
structuredClone example usage:
const originalArray = [1, 2, 3];
const newArray = structuredClone(originalArray);
newArray.push(4);
console.log('originalArray', originalArray); // [1, 2, 3]
console.log('newArray', newArray); // [1, 2, 3, 4]
Upvotes: 0
Reputation: 1
If you want to clone array you can do like this
function cloneArray (array) {
const newArray = new Array(array.length)
.fill()
.map(_=> new Array(array.length)
)
for (let i = 0; i < array.length; i++) {
for (let j = 0; j < array[0].length; j++) {
newArray[i][j] = array[i][j];
}
}
return newArray;
}
const arr1 = [[1,2,3],[4,5,6],[7,8,9]]
const arr2 = cloneArray(arr1);
arr2[0][0] = 100;
console.log("this is arr1");
arr1.forEach((val)=>console.log(val));
console.log("this is arr2");
arr2.forEach((val)=>console.log(val));
Upvotes: 0
Reputation: 59
let newBoard = JSON.parse(JSON.stringify(board));
This did the trick. I figured it had something to do with being a shallow copy, but then I'm not sure what the point of creating a copy of the same array is if you can't separately modify it?
Upvotes: 2
Reputation: 91
Array.prototype.slice()
does a shallow clone. Which means if the array is contains objects, the clone will be referring to the same object.
board
is a 2-dimensional array. Each element in this array is an array. board.slice()
provides a shallow copy of the board
. If you do something like newBoard[0] = ....
, original board
doesn't change. But each element within newBoard
, for example newBoard[0]
is still referring to the same object as before board[0]
. Any change in the form of newBoard[0][0] = ...
will also update board[0][0]
.
In order to fix this, you'd need to deep clone. There are libraries performing this already. But if your use case is just 2-dimensional array, you could do something like this:
newBoard = board.map(row => row.slice());
Upvotes: 1
Reputation: 636
This is because .slice()
only performs a shallow copy, therefore some of the values are still referenced from the original array. Please see more detailed explanation in the answers to this question: What is the difference between a shallow copy and a deep copy with JavaScript arrays?
Upvotes: 2