目前我正在开发一个用于javascript中四行的Minimax算法。我决定在数组中存储可能的移动,继续在每个分支的数组中嵌套数组。
但是,当我尝试编辑数组中的某个值时,它会编辑同一列中的所有其他值。
代码:
var BOARD = [
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]
];
// Put 3 x 2D Arrays into one 3D Array
var NODE_TREE = [BOARD, BOARD, BOARD];
NODE_TREE[1][2][0] = 2;
console.log(NODE_TREE);
Chrome V8解释器输出:
[ [ [ 0, 0, 0 ], [ 0, 0, 0 ], [ 2, 0, 0 ] ],
[ [ 0, 0, 0 ], [ 0, 0, 0 ], [ 2, 0, 0 ] ],
[ [ 0, 0, 0 ], [ 0, 0, 0 ], [ 2, 0, 0 ] ] ]
应该发生什么,但不要:
[ [ [ 0, 0, 0 ], [ 0, 0, 0 ], [ 0, 0, 0 ] ],
[ [ 0, 0, 0 ], [ 0, 0, 0 ], [ 2, 0, 0 ] ],
[ [ 0, 0, 0 ], [ 0, 0, 0 ], [ 0, 0, 0 ] ] ]
Javascript似乎忽略了第一个维度索引号。只有当我使用嵌套在数组中的现有数组时才会发生此问题。如果我要从头开始制作3D数组,那么这个错误就不会发生。
答案 0 :(得分:1)
当您将BOARD
3次放入数组时,您不会"复制"对于新数组的项目,实际上只是创建了对原始BOARD
数组的3个引用。
因此,对这些引用中的任何一个进行的任何更改都将反映在BOARD
的所有实例中。
如果要在3d阵列中创建3个不同的阵列,则需要克隆或复制阵列。您可以通过映射外部数组并使用Array.prototype.slice()复制内容来完成此操作;
var BOARD = [
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]
];
// function to map and copy arrays with .slice()
function sliceArrays (outerArray){
return outerArray.map((arr)=>{
return arr.slice()
});
}
var NODE_TREE = [sliceArrays(BOARD), sliceArrays(BOARD), sliceArrays(BOARD)];
NODE_TREE[1][2][0] = 2;
console.log(NODE_TREE);
//[ [ [ 0, 0, 0 ], [ 0, 0, 0 ], [ 0, 0, 0 ] ],
// [ [ 0, 0, 0 ], [ 0, 0, 0 ], [ 2, 0, 0 ] ],
// [ [ 0, 0, 0 ], [ 0, 0, 0 ], [ 0, 0, 0 ] ] ]

答案 1 :(得分:1)
对于懒惰的初始化,您可以使用已解析的JSON字符串。
这会生成一个独立的对象,而不会引用原始对象。
var BOARD = [
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]
],
JSON_BOARD = JSON.stringify(BOARD),
NODE_TREE = [JSON.parse(JSON_BOARD), JSON.parse(JSON_BOARD), JSON.parse(JSON_BOARD)];
NODE_TREE[1][2][0] = 2;
console.log(NODE_TREE);

.as-console-wrapper { max-height: 100% !important; top: 0; }