Object.values()没有更新变量



我将变量G.playerStatsDifference定义为对象数组:

playerStatsDifference: [{
carpenter: 0,
wood: 0,
gunman: 0,
gunpowder: 0,
merchant: 0,
gold: 0,
fleet: 0,
flagship: 0,
}, {
carpenter: 0,
wood: 0,
gunman: 0,
gunpowder: 0,
merchant: 0,
gold: 0,
fleet: 0,
flagship: 0,
}]

该变量的意义在于计算频繁变化的G.playerStats之间的差值。

我计算差值的函数是:

const oldPlayerStats = JSON.parse(JSON.stringify(G.playerStats));
statsDifference(G, oldPlayerStats);  
for (let p = 0; p < 2; p++) { 
for (let s = 0; s < 8; s++) { 
Object.values(G.playerStatsDifference[p])[s] = Object.values(G.playerStats[p])[s] - Object.values(oldPlayerStats[p])[s];
}    
}

期望的输出是playerStatsDifference

当运行一些测试时,我做了一些控制台日志记录,它给了我正确的计算,但是G.playerStatsDiffence不会更新。

下面是一些测试,计算是正确的:

console.log("Current wood is " + Object.values(G.playerStats[0])[1]); //Current wood is 5
console.log("Old wood is " + Object.values(oldPlayerStats[0])[1]); //Old wood is 10
console.log(Object.values(G.playerStats[0])[1] - Object.values(oldPlayerStats[0])[1]); //-5

我想也许我在循环中做错了什么,所以后来我尝试了以下操作:

Object.values(G.playerStatsDifference[0])[1] = Object.values(G.playerStats[0])[1] - Object.values(oldPlayerStats[0])[1];

然而,这也不起作用。话虽如此,下面的操作是可行的:

G.playerStatsDifference[0].wood = Object.values(G.playerStats[0])[1] - Object.values(oldPlayerStats[0])[1];

所以看起来我对G.playerStatsDifference上的Object.values有一些问题。有人知道为什么会这样吗?我该如何在循环中运行它?

= = = = =

编辑:正如评论中指出的那样,我的问题有点令人困惑,所以我将尝试在这里澄清……

G.playerStatsDifference的值应该跟踪G.playerStats的前一个值与G.playerStats的当前值之间的差值。

为此,我将oldPlayerStats的值设置为等于G.playerStats,然后将G.playerStats更新为其新值。

然后我需要遍历对象数组并从oldPlayerStats中减去G.playerStats的值。这将产生G.playerStatsDifference

的值这就是循环的作用,遍历每个对象键并进行计算。

希望这能提供一些清晰。对不起,我的问题写得不好。

const diffBetweenObjectValues = (a, b) => {
return Object.entries(a).reduce((result, [aKey, aVal]) => {
result[aKey] = aVal - (b[aKey] ?? 0);
return result;
}, {});
}
const stats = { a: 1, b: 2 };
const updatedStats = { a: 1, b: 1 };
// Initial player stats are { a: 1, b: 2 }
const player = { stats: stats, diff: {} };
// Set the diff, value is { a: 0, b: 1 }
player.diff = diffBetweenObjectValues(player.stats, updatedStats);
// Actually update the stats, value is { a: 1, b: 1 }
player.stats = updatedStats;

注意,如果一个键在b中存在,但在a中不存在,它将被忽略。还要注意,如果所有的属性值都是数字,那么只有才能正常工作。

你可以把状态转换放在一个函数中,只在你需要更新状态时运行它(就像游戏循环的每一次滴答)。

对评论的回应

好,让我们添加另一个辅助函数

const zip = (a, b) => a.map((x, i) => [x, b[i]]);
const players = [...]; // array of players
const statUpdates = [...];   // array of stat updates
zip(players, statUpdates).forEach(([player, stats]) => {
player.diff = diffBetweenObjectValues(player.stats, stats);
player.stats = stats;
});

Zip将玩家数组和状态更新数组成对地组合在一起,然后使用forEach对它们进行迭代,解构比特,并运行更新。你也可以只使用for循环,它更快,但更难阅读,更容易出错(例如off-by- 1错误)。我会坚持使用这个版本,除非你的分析器告诉你它太慢了。

更新2

const currentStats = [{ a: 1, b: 2 }, {a: 3, b: 2 }];
const updatedStats = [{ a: 0, b: 1 }, {a: 4, b: 1 }];
const diffedStats = zip(currentStats, updatedStats).map(([current, updated]) => {
return diffBetweenObjectValues(current, updated);
});

// for testing purposes, create an object with some random stats
const randomPlayerStats = () => Object.fromEntries(
['carpenter','wood','gunman','gunpowder','merchant','gold','fleet','flagship']
.map(k=>[k,Math.random()*10|0]));
// array of the last player stats recorded for each player
let lastPlayerStats = [];
// create a new object from the existing object, subtracting each entry
// from the old object from the entry from the new object
// note: uses the ?? operator so that if there is no last object yet,
// the last object value will be treated as being zero
const difference = (playerStats, lastPlayerStats) => {
let r = Object.fromEntries(Object.entries(playerStats).map(([k,v])=>
[k, v-(lastPlayerStats?.[k]??0)]));
lastPlayerStats = playerStats;
return r;
};
// simulate 5 rounds of the game, with 2 players in the game
const playerCount = 2;
const simulatedRounds = 5;
for(let c=0;c<simulatedRounds;c++) {
let playerStats = [...Array(playerCount).keys()].map(i=>randomPlayerStats());
let playerStatsDifference = playerStats.map((s,i)=>
difference(s, lastPlayerStats[i]??{}));
console.log('playerStats:');
console.log(playerStats);
console.log('playerStatsDifference:');
console.log(playerStatsDifference);
}

最新更新