プロが教えるわが家の防犯対策術!

Google Apps Scriptを勉強中の者です。

例えば成績処理のようなことをする場合に成績の順位を出すような処理が必要です。二次元配列をsortで降順に並び替えるのは簡単ですが、順位を出す場合は、同点の場合は同順位になりますが、それを二次元配列を使ってするにはどうしたらいいのでしょうか?indexOfでは同順位の処理はできないですよね?

例えば以下のように同点の者が複数いる場合の処理方法がわかりません。

生徒 点数 順位
A   85   1
B   82   2
C   82   2
D   82   2
E   80   5
F   78   6
G   78   6
H   76   8
I   71   9
J   70   10

VBAだとworksheetfunction.rankという形でVBAの関数を使えますが、GASでもそういうことはできるのでしょうか?

ネットで検索してもわからないので、解決法を教えていただければ助かります。どうぞよろしくお願いいたします。

A 回答 (4件)

配列の並べ替えができたのならば、あとは順位を付け足しましょう



var 比較 = (a,b) => a.点数 - b.点数;
配列.sort( 比較 );
for (var i=0; i<配列.length; i++) {
_ var 順位 = i+1;
_ if (0 < i && 比較(配列[i-1], 配列[i]) == 0) {
_ _ 順位 = 配列[i-1].順位;
_ }
_ 配列[i].順位 = 順位;
}
var Dの順位 = 配列.find(e => e.生徒 == "D").順位 // == 2
var Eの順位 = 配列.find(e => e.生徒 == "E").順位 // == 5
    • good
    • 0
この回答へのお礼

早速の回答ありがとうございます。新年度の準備でバタバタしていて返信遅れてすみません。

お示しいただいた方法がまだよく理解できないのですが、調べてみたいと思います。もしこういった順位の出し方を解説しているようなサイトがあれば教えていただければ助かります。ソートについてはたくさん解説サイトがあるのですが、順位については見つけられませんでした。

お礼日時:2024/04/05 05:38

const data = [


['H',76],
['B',82],
['A',85],
['E',80],
['I',71],
['J',70],
['C',82],
['F',78],
['G',78],
['D',82],
];
const output = data.sort((a,b)=>b[1]-a[1])
.reduce((p,c,i)=>{
const rank = (i > 1 && p[p.length - 1][1] === c[1]) ? p[p.length - 1][2] : i + 1;
c.push(rank);
p.push(c);
return p;
}, []);
console.log(output);

reduceについては、以下が参考になります。
https://developer.mozilla.org/ja/docs/Web/JavaSc …
    • good
    • 0
この回答へのお礼

忙しい中、回答ありがとうございます。

お示しいただいたコードで順位がちゃんとだせることを確認いたしました。ちょっとどのように処理しているかが、今はわからないので、勉強したいと思います。

reduceというメソッドは知ってはいましたが、使ったこともなく何のためにあるかもよくわかっていませんでした。お示しいただいたサイトを見たのですが、私にはよく理解できませんでした。(~_~;)

また質問することがあるかもしれませんが、よろしくお願いいたします。m(__)m

お礼日時:2024/04/06 19:53

No2です。



>配列で処理できないかと考えているところです。
それに該当する回答がNo1様の回答です。(=No2にも書きました)

>ソートについてはたくさん解説サイトがあるのですが、
>順位については見つけられませんでした。
ソートに関しては、先人達の成果がいくつかの代表的なロジックとしてまとめられています。
一目でその内容が理解できれば良いのですが、そうでもないので、解説サイトがいろいろあるのでしょう。
また、複数のロジックがどう違うのかも、解説が欲しくなったりしますよね。
(javascriptの場合は、sortメソッドが用意されているので、ロジックを知る必要もないですけれど)

これに対して、「順位付け」は特に解説するほどの内容がないので、解説サイトがないだけではないでしょうか?
(机上作業で、ソートされていれば順位付けに苦労する人はいないでしょう)


自前で処理するのなら、ソート済みの配列を順に見て行って、
「一つ前と値が同じなら、一つ前と同じ順位、そうでなければ配列の添え字(=単独の場合の順位と同じ)を順位とする」
というロジックで一巡すれば良いだけですから。
(机上やシート上で作業列に順位を出すのと、考え方は全く同じです)

※ 配列の添え字が0始まりの場合は、順位は「添え字+1」と考える
 (序数は1始まりなので)
※ 配列の最初の値を処理する際、「その一つ前」が存在しないので、無条件で順位1とする
あたりに注意しておく必要はありますが。
    • good
    • 0
この回答へのお礼

再度の回答ありがとうございます。

いろいろなサイトを見て、なんとかNo.1のOgre7077様の書いていることがなんとなく理解できました。

とりあえずは、自分のやりたいと思っていた配列を使って順位を出すことはできたのですが、まだまだ勉強しないといけないことを痛感しました。ありがとうございました。

お礼日時:2024/04/06 19:43

こんにちは



計算で行う方法は、既にNo1様の回答にある通りと思いますが・・

>VBAだとworksheetfunction.rankという形でVBAの関数を使えますが、~
それは、VBAというよりはエクセルのシート関数のことですよね?
スプレッドシートなら、同様にシートで関数を利用すれば、同じことは可能でしょう。
https://support.google.com/docs/answer/3094098?s …

GASの場合は、WorksheetFunction のようにスクリプト内でシート関数を呼び出す仕組みはないようですので、シート上で処理する必要がありますけれど。

丁度、逆に、
>二次元配列をsortで降順に並び替えるのは簡単ですが~
VBAの場合はSORTメソッドのような機能がないので、自作で並べ替え計算をするか、シート上で並べ替え機能を利用するかになるのと同様(=逆ですが)のことと思います。
    • good
    • 0
この回答へのお礼

早速の回答ありがとうございます。GASではスクリプト内でシート関数を呼び出すことはできないこと、理解いたしました。

GAS内でできないのであれば、作業列みたいなものを作って、そこに関数を入れて計算して、それを配列に入れて処理しようと考えたのですが、人数が多いとタイムリミットの6分を超えそうなので、配列で処理できないかと考えているところです。

お礼日時:2024/04/05 05:41

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


このQ&Aを見た人がよく見るQ&A