gpt4 book ai didi

javascript - 如何分配给闭包内外部嵌套哈希中的键

转载 作者:行者123 更新时间:2023-12-03 05:24:30 25 4
gpt4 key购买 nike

帮助我为嵌套循环中的对象赋值。

我实际需要调试的代码如下所示:

  // Next states
let nextVal = undefined
let nextBoard = undefined
let next_player_value = undefined

shuffle(Board.rowCols).forEach(c => {
shuffle(Board.rowCols[c]).forEach(r => {
if (board[c][r] === undefined) {
board[c][r] = player_state // let's test the current player moving to this location
next_player_value = this.getMinMaxPlayerValue(!player_state)
let minmax = AI.recurseMinMax(next_player_value, board, depth+1)
let value = minmax[0]
if (((player_state===this.getState()) && (nextVal === undefined || value > nextVal)) || // its the AI, and the value increases
((player_state!==this.getState()) && (nextVal === undefined || value < nextVal))) { // its the player, and the value decreases
nextBoard = Object.assign({},board)
nextVal = value
}
board[c][r] = undefined
}
})
})
return [nextVal, nextBoard]

如果您观察调试器,会发生什么情况,它正确地将不同的可能的板位置分配给 nextBoard,但是当它在返回 return 的途中退出外部 block 时> 语句,nextBoard 发生变化。它不会变得未定义!相反,它成为当前的 Board.state,其中没有任何新的移动(应该存在的移动与其他空棋盘空间一样处于未定义状态)。

player_state never 未定义,但它是 recurseMinMax 的参数(这是包含函数这段代码)。事实上,它总是truefalse。我无法轻松替换它 - 我尝试将分配更改为 !!player_stateObject.assign({}, player_state)

这不是嵌套循环或闭包的问题。这里有几个例子:

从控制台

> let a; b = {}; keys=[1]; values =[2];
keys.forEach(key => {
values.forEach(value => {
b[key]=value;
a = Object.assign({},b)
})
})
< undefined
> a
< Object {1: 2}

为什么这不起作用:

损坏的示例(使用数组而不是哈希)

let nextBoard = undefined
[0,1,2].forEach(i =>{
[0,1,2].forEach(j =>{
if (board[i][j] == null) {
board[i][j] = player;
var value = recurseMinimax(board, !player)[0];
if ((player && (nextVal == null || value > nextVal)) || (!player && (nextVal == null || value < nextVal))) {
nextBoard = Object.assign({},board)
nextVal = value
}
board[i][j] = null;
}
})
})

这就像我的实际代码一样。

应该是当前的Board.state,但其中有一个额外的移动,该移动在board[i][j] = player;处分配; .

现在有趣的是,当我们使用这样的数组时,我可以很容易地让它工作:

工作示例(使用数组而不是嵌套哈希)

[0,1,2].forEach(i =>{
[0,1,2].forEach(j =>{
if (board[i][j] == null) {
board[i][j] = player;
var value = recurseMinimax(board, !player)[0];
if ((player && (nextVal == null || value > nextVal)) || (!player && (nextVal == null || value < nextVal))) {
nextBoard = board.map(function(arr) {
return arr.slice();
});
nextVal = value
}
board[i][j] = null;
}
})
})

这个效果很好。

问题是,我的实际板不是嵌套数组,而是嵌套哈希:

Board.state = {}; 
['a','b','c'].forEach(c => {
Board.state[c]={};
[1,2,3].forEach(r => Board.state[r]=undefined)
});

最佳答案

发生这种情况是因为 Object.assign({},board) 采用浅拷贝,即 board 中的行将与您获得的相同引用Object.assign 的返回值。

您应该进行深拷贝。

一种巧妙的方法是使用 JSON:

nextboard = JSON.parse(JSON.stringify(board));

...尽管这仅在 board 仅包含 JSON 支持的基本类型时有效(因此没有函数、集合、映射...)。

参见How to deep clone in JavaScript对于一些其他解决方案

例如this answer这是我自己的手:

function deepClone(obj, hash = new WeakMap()) {
if (Object(obj) !== obj) return obj; // primitives
if (hash.has(obj)) return hash.get(obj); // cyclic reference
var result = Array.isArray(obj) ? []
: obj.constructor ? new obj.constructor() : Object.create(null);
hash.set(obj, result);
if (obj instanceof Map)
Array.from(obj, ([key, val]) => result.set(key, deepClone(val, hash)) );
return Object.assign(result, ...Object.keys(obj).map (
key => ({ [key]: deepClone(obj[key], hash) }) ));
}

...一旦您拥有该功能,您就可以执行以下操作:

nextboard = deepClone(board);

该函数中的某些功能可能对您来说没有用处(例如对循环引用和Map的支持),因此您可以根据您的需要对其进行简化。

关于javascript - 如何分配给闭包内外部嵌套哈希中的键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41209595/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com