0

ここでの目標は、ゲーム内の各ユーザーのキーを持つ「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);
 };

この時点ではまだ調子が良いです。これにより、これまでにゲームで行われた 2 週間の 2 つの異なる「合計」配列が得られました。

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' が紛らわしく見えないようにします。これは、配列の最初の位置ではなく 0 の位置に 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');
      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
}

....などですが、すべてのユーザー向けです。すべてのユーザーにまったく同じ値を何度も割り当てています。ループした最後の「d」値だったという理由だけで、すべてのユーザーが -4.27 と -1.41 になります。

コードにtallys[weekSum.username]があるときに、すべてのユーザー名を最後の関連値で更新するのはなぜですか?

助けてくれてありがとう!


編集:皆様のご協力に改めて感謝いたします。コメントでの@Bergiの答えは正しいです。彼が提案するように「タリー」を作成する最初のコードを編集すると、すべてが正常に機能します。最初の「週」配列を複製するという提案された回答としてマークした@vothanhdatのアプローチも問題を解決します。

let tallys = {};
users.forEach(user => {
  let weeks = [];
  for (let i=0; i < maxWeek+1; i++) {
     weeks.push(0)
  };
  tallys[user] = weeks;
});
4

1 に答える 1

-1

tallys[user]あなたの問題は、同じweeks配列へのすべての参照です。

例:

let a = [1,2,3]
console.log(a) // [1,2,3]
let b = a // now a & b is reference to the same array
b[0] = 100 
console.log(a) // [100,2,3]

したがって、解決策は、すべてのユーザーにアレイの週を複製することです

const maxWeek = 25;
let weeks = [];
for (let i = 0; i < maxWeek + 1; i++) {
  weeks.push(0)
};
let tallys = {};
users.forEach(user => {
  tallys[user] = [...weeks] //Clone week array
});
于 2019-10-29T11:08:35.900 に答える