【发布时间】:2019-10-29 09:46:14
【问题描述】:
我的目标是创建一个对象“tallys”,它为游戏中的每个用户提供一个键,分配给这些用户键的值是一个数组,表示每周在游戏中赢得的美元值。首先,我通过以下代码为游戏中的每个用户分配一个长度为 26(表示游戏中的 26 周)的数组,其中包含 26 个值“0”来表示每周 0 美元的值:
const maxWeek = 25;
let weeks = [];
for (let i=0; i < maxWeek+1; i++) {
weeks.push(0)
};
let tallys = {};
users.forEach(user => {
tallys[user] = weeks;
});
...导致这样的对象:
tallys is {
michaeljpow: [
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
],
'Mr. Cheeseburger': [
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
],
'brewster.stanislaw': [
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
],
... etc
}
然后,我运行一点 for 循环来计算每个用户每周的总数......这里的“j”变量从第 1 周开始,并且循环运行的时间与游戏运行的时间一样多,像这样:
for (let j=1; j<wk+1; j++) {
let sums = await BonusEvents().where({week: j}).sum('dollars_total as d').groupBy('username').select('username');
console.log('sums for week ', j, ' are ', sums);
};
此时我的状态仍然很好——这让我得到了我想要的,两个不同的“总和”数组,用于迄今为止在游戏中发生的两周:
sums for week 1 are [
{ d: -4.27, username: 'Mr. Cheeseburger' },
{ d: -4.27, username: 'dannuzio' },
{ d: 11.29, username: 'james.johnsonf' },
{ d: -4.27, username: 'brewster.stanislaw' },
{ d: 16.47, username: 'eric.wj.clarke' },
{ d: -4.27, username: 'mikeduin' },
{ d: 11.29, username: 'BH84' },
{ d: -4.27, username: 'kevsims' },
{ d: 11.29, username: 'michaeljpow' },
{ d: 47.58, username: 'superbkn' },
{ d: -4.27, username: 'whpfwashington' },
{ d: -4.27, username: 'benjamininghram' }
]
sums for week 2 are [
{ d: -1.41, username: 'benjamininghram' },
{ d: -1.41, username: 'BH84' },
{ d: -1.41, username: 'brewster.stanislaw' },
{ d: -1.41, username: 'dannuzio' },
{ d: -1.41, username: 'eric.wj.clarke' },
{ d: -1.41, username: 'james.johnsonf' },
{ d: -1.41, username: 'kevsims' },
{ d: -1.41, username: 'michaeljpow' },
{ d: -1.41, username: 'mikeduin' },
{ d: -1.41, username: 'Mr. Cheeseburger' },
{ d: 14.06, username: 'superbkn' },
{ d: -1.41, username: 'whpfwashington' },
]
所以这就是事情变得混乱的地方。我修改了前面的函数,以便每周对我的“sums”数组执行一次 forEach,并设计修改“tallys”对象以修改分配给每周的数组位置,并为每个用户使用适当的美元值。 (另外,以免这里的“j-1”看起来令人困惑——那是因为我希望将 1 的游戏周分配到数组中的 0 位置而不是第一个位置):
for (let j=1; j<wk+1; j++) {
let sums = await BonusEvents().where({week: j}).sum('dollars_total as d').groupBy('username').select('username');
sums.forEach(weekSum => {
tallys[weekSum.username][j-1] = weekSum.d;
console.log('tallys are ', tallys);
})
};
所以我希望在这里得到这样的结果:
tallys = {
mikeduin: [-4.27, -1.41, 0, 0, 0 ... etc],
superbkn: [47.58, 14.06, 0, 0, 0 ... etc],
... etc
}
... 为每个用户设置适当的值。然而!一旦所有循环等完成,这就是我作为我的计数对象的最终结果:
tallys are {
michaeljpow: [
-4.27, -1.41, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0
],
'Mr. Cheeseburger': [
-4.27, -1.41, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0
],
superbkn: [
-4.27, -1.41, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0
],
...etc
}
.... 等等,但对于每个用户。它一遍又一遍地为每个用户分配完全相同的值——它们都以 -4.27 和 -1.41 结束,只是因为那是循环通过的最后一个 'd' 值。
为什么当我的代码中有 tallys[weekSum.username] 时,它会使用最后一个相关值更新每个用户名,以便每次在 tallys 对象中只更新一个用户名??
提前感谢您的帮助!
编辑:再次感谢大家的帮助。 @Bergi 在 cmets 中的回答是正确的。当我按照他的建议编辑创建“计数”的初始代码时——一切正常。我标记为建议答案的@vothanhdat 方法,在该方法中我克隆了初始的“weeks”数组,也解决了这个问题。
let tallys = {};
users.forEach(user => {
let weeks = [];
for (let i=0; i < maxWeek+1; i++) {
weeks.push(0)
};
tallys[user] = weeks;
});
【问题讨论】:
-
您没有向我们展示创建
tallys的代码,这可能是错误所在 - 通过将同一个数组分配给多个事物。 -
@Bergi 谢谢 - 我现在已经添加了该代码。我非常感谢您的反馈,但我不确定情况是否如此,因为当我在 sums.forEach 中运行最后一个 console.log('tallys are ', tallys) 时 - 它显示每个用户键的值都更改为相同的数组,这向我表明,由于某种原因,代码的 tallys[weekSum.username] 部分无法正常运行。
-
不,它们是 相同 数组的原因是您在循环中用 same
weeks数组填充tallys。将创建weeks数组的代码放在users.forEach循环中。和求和码没关系,已经晚了。 -
@unvrsltravlr 我在使用 forEach() 时遇到了同样的异步等待问题。在使用你的 forEach() 的内部使用 promise.all([])
-
我尝试按照您的方式进行操作,但尽管我没有使用 BonusEvents(),但一切正常。请你仔细检查一下。我做了同样的事情:jsfiddle.net/dani19/5eLg1chy/15
标签: javascript node.js asynchronous foreach object-notation