こんな感じですかね〜
javascript
1const XX = [
2 ["国語","英語","数学","合計","順位"],
3 [30,65,55,0,0],
4 [45,60,65,0,0],
5 [50,65,65,0,0],
6 [60,55,60,0,0],
7 [70,45,50,0,0],
8 [40,75,45,0,0],
9 [50,45,90,0,0]
10];
11
12XX.forEach((data, i) => {
13 if (i > 0) {
14 data[3] = data[0] + data[1] + data[2];
15 }
16});
17
18console.log(XX);
19
20const ranking = [0, ...XX.slice(1).map((data, i) => [i, data[3]]).sort((a, b) => b[1] - a[1]).map(([i]) => i+1)];
21
22console.log(ranking);
23
24XX.forEach((data, i) => {
25 if (i > 0) {
26 data[4] = ranking.findIndex(j => j === i);
27 }
28});
29
30console.log(XX);
31
???? 動作確認用サンプル @codepen
追記
質問の画像にも出てきますが、
という配列をどうやって作るか? がこの問題の考えどころのひとつです。
各データ行において、三科目の合計は、XXの各要素である配列のインデクス3の要素に入ってくるので、この値を比較するような比較関数をsort
メソッドに与えてソートするわけですが、XX
の最初の要素は
["国語","英語","数学","合計","順位"]
という、各データの名前の文字列を持つヘッダ情報なので、この行もソートの対象に含めてしまうと、"合計"という文字列と、他の行の合計値である数値とを比較することになるので、ひと工夫が必要です。
先の回答では、このひと工夫をしないで済むように、ヘッダ行をソート対象から除いていますが、かえって読みにくいコードになってしまっているかもしれません。
ヘッダ行(XXの先頭)もソート対象に含めつつ、
という配列、ranking
を得るには、たとえば以下のようにします。
javascript
1const ranking = [...Array(XX.length)].map((_, i) => i).sort((i1, i2) => {
2 const [score1, score2] = [i1, i2].map(i => i > 0 ? XX[i][3] : Number.MAX_SAFE_INTEGER);
3 return score2 - score1;
4});
???? 動作確認用サンプル @codepen
これは、ソートで使う比較関数内においては、ヘッダ行にも合計の数値があるかのように見立てて、その値は Number.MAX_SAFE_INTEGER という非常に大きな数であると見なすというひと工夫によって、先頭要素もソート対象にしつつ、意図した結果を得るようにしています。
または、以下でも [0,7,3,4,2,5,6,1]の配列 ranking
を作れます。
javascript
1const ranking = [...Array(XX.length)].map((_, i) => i).sort(
2 (i1, i2) => (i1 === 0 || i2 === 0) ? i1 - i2 : XX[i2][3] - XX[i1][3]
3);
???? 動作確認用サンプル @codepen