javascriptで平均値を求めたいのですが

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さんの平均値 *点

この場合、同じユーザ名のところを集めて点数を足していってそれぞれ数で割って平均値を出すやり方がいまいちわかりません。ユーザ名ごとに点数を足すやり方は連想配列を使ってやるのでしょうか?(ユーザ名をキーにする?)

アドバイス頂ければ幸いです。

回答の条件
  • 1人5回まで
  • 登録:
  • 終了:2016/12/06 16:36:53

ベストアンサー

id:a-kuma3 No.1

回答回数4968ベストアンサー獲得回数2151

ユーザ名をキーにした連想配列にデータを貯めこんでいく、という方針で良いと思います。
例えば、こんな感じ。

// 集計するデータ
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]);
}

求めた平均値と名前を持った配列を別に作り、それを平均得点順に並べ替えてます。

他3件のコメントを見る
id:a-kuma3

キーではなくaverageを点数が高い順に並べ替えするのはどうしたらいいのでしょうか?

回答に追記しました。

2016/12/01 18:22:27
id:kajironpu

ありがとうございます。 無事成功しました。averageの結果をもう一度、連想配列に戻すことばかり考えていたのですが、平均値を計算した結果とユーザ名を別の配列に入れてそれをソートするアイデアが思い浮かびませんでした。
いろいろと勉強になりました。ありがとうございます。

2016/12/01 21:23:09

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません