Aさん、Bさん、Cさんのスコアデータが配列に順番に入っています。
Aさん、10点
Bさん、50点
Cさん、100点
Aさん、22点
Bさん、44点
Bさん、40点
Cさん、100点
それぞれ日付ごとにスコアデータを記録したものを順番に配列に入れています。
data =[A,10月2日,10,B,10月3日,50,C,11月1日,100,A,12月1日,22,B,12月1日,44,B,11月3日,40,C,10月10日,100]のように
ユーザ名、日付、点数という履歴のデータを配列に順番にいれているのですが
ここからそれぞれのユーザーごとに平均値を求めたいと思っています。
例)
Aさんの平均値 *点
Bさんの平均値 *点
Cさんの平均値 *点
この場合、同じユーザ名のところを集めて点数を足していってそれぞれ数で割って平均値を出すやり方がいまいちわかりません。ユーザ名ごとに点数を足すやり方は連想配列を使ってやるのでしょうか?(ユーザ名をキーにする?)
アドバイス頂ければ幸いです。
ユーザ名をキーにした連想配列にデータを貯めこんでいく、という方針で良いと思います。
例えば、こんな感じ。
// 集計するデータ var data =[ "A", "10月2日", 10, "B", "10月3日", 50, "C", "11月1日", 100, "A", "12月1日", 22, "B", "12月1日", 44, "B", "11月3日", 40, "C", "10月10日", 100 ]; // 合計点数と回答数を入れておく連想配列 var info = {}; // 合計点数と回答数をユーザ毎に集計する for (var i = 0 ; i < data.length ; i += 3) { // みっつ毎 var name = data[i]; // 一番目が名前 var point = data[i+2]; // 三番目が点数 var e = info[name]; // 合計点数と回答数を取り出す if (! e) { // 初めてのカウントだったら e = {}; // 合計点数=0、回答数=0 のデータを用意 e.sum = 0; e.n = 0; } e.sum += point; // 合計点数をカウント e.n += 1; // 回答数をカウント info[name] = e; // カウントしたデータを入れ直す } // 集計したデータから平均値を算出する for (var name in info) { // 連想配列のデータを順番に取り出す var e = info[name]; // キーが名前 var ave = e.sum / e.n; // 平均値 // 計算した平均値などをコンソールに出力 console.log(name, e.sum, e.n, ave); }
キーではなくaverageを点数が高い順に並べ替えするのはどうしたらいいのでしょうか?
先の回答を、ちょっと書き換えてみました。
// 集計するデータ var data =[ "A", "10月2日", "10", "B", "10月3日", "50", "C", "11月1日", "100", "A", "12月1日", "22", "B", "12月1日", "44", "B", "11月3日", "40", "C", "10月10日", "100" ]; // 合計点数と回答数を入れておく連想配列 var info = {}; // 合計点数と回答数をユーザ毎に集計する for (var i = 0 ; i < data.length ; i += 3) { // みっつ毎 var name = data[i]; // 一番目が名前 var point = parseInt(data[i+2]); // 三番目が点数 var e = info[name]; // 合計点数と回答数を取り出す if (! e) { // 初めてのカウントだったら e = {}; // 合計点数=0、回答数=0 のデータを用意 e.sum = 0; e.n = 0; } e.sum += point; // 合計点数をカウント e.n += 1; // 回答数をカウント info[name] = e; // カウントしたデータを入れ直す } // 平均得点と名前を入れる配列 var ave_list = []; // 集計したデータから平均値を算出する for (var name in info) { // 連想配列のデータを順番に取り出す var e = info[name]; // キーが名前 var ave = e.sum / e.n; // 平均値 // 計算した平均値と名前を配列に入れる ave_list.push([ave, name]); } // 平均得点の大きい順に並べ替える ave_list = ave_list.sort(function(a, b) { return b[0] - a[0]; }); // 名前と平均得点をコンソールに出力する for (var i = 0 ; i < ave_list.length ; ++i) { console.log(ave_list[i][1], ave_list[i][0]); }
求めた平均値と名前を持った配列を別に作り、それを平均得点順に並べ替えてます。
回答に追記しました。
2016/12/01 18:22:27ありがとうございます。 無事成功しました。averageの結果をもう一度、連想配列に戻すことばかり考えていたのですが、平均値を計算した結果とユーザ名を別の配列に入れてそれをソートするアイデアが思い浮かびませんでした。
2016/12/01 21:23:09いろいろと勉強になりました。ありがとうございます。