カスタムソート
CoddyのGDScriptジャーニー「ロジックとフロー」セクションの一部。レッスン 51/78。
sort()は配列を昇順に並べ替え、配列自体を変更します。数値は小さいものから大きいものへ並び、文字列はmin()と同じ順序で、大文字が先になります。その後、reverse()で降順になります。
var scores := [40, 95, 12, 70]
scores.sort()
print(scores) # [12, 40, 70, 95]
scores.reverse()
print(scores) # [95, 70, 40, 12]それ以外の順序にするには、比較関数を指定してsort_custom()を呼び出します。この関数は2つの要素aとbを受け取り、aをbより前に置く必要がある場合にtrueを返します。関数名を指定して渡し、括弧は付けません。
func by_length(a: String, b: String) -> bool:
return a.length() < b.length()
func _ready():
var words := ["banana", "fig", "kiwi"]
words.sort_custom(by_length)
print(words) # ["fig", "kiwi", "banana"]比較処理では要素の中身を確認できます。これは、"hp"が最も大きい辞書を先頭にします。
func by_hp(a: Dictionary, b: Dictionary) -> bool:
return a["hp"] > b["hp"]このソートは安定ではありません。同じと判定される要素は、どの順序になるか分かりません。同順位が重要な場合は、最初のフィールドが同じときに2つ目のフィールドを比較します。
func by_score_then_name(a: Dictionary, b: Dictionary) -> bool:
if a["score"] != b["score"]:
return a["score"] > b["score"]
return a["player"] < b["player"]sort_custom()はArrayにはありますが、split()が返すPackedStringArrayにはないため、まずArray(...)で変換してください。また、sort_custom(func(a, b): return a > b)のように、比較処理をインラインで記述する方法にも出会います。この形式はラムダであり、「高度な関数」の章で取り上げます。
チャレンジ
簡単プログラムは2行を読み込みます。1行目はスペース区切りの整数、2行目はスペース区切りの単語です。与えられたコードでは、それらをnumbers(整数の配列)とwords(文字列の配列)に格納します。
- トップレベルに比較関数
by_length(a: String, b: String) -> boolを書いてください。短い単語が先になり、同じ長さの単語はアルファベット順になります。 - 4行を出力してください。数値を昇順にしたもの、数値を降順にしたもの、単語をアルファベット順にしたもの(
sort()を使用)、そしてsort_custom(by_length)で並べ替えた単語です。
入力が5 3 8 1 2とelephant cat dolphin beeの場合、出力は次のとおりです。
Ascending: [1, 2, 3, 5, 8]
Descending: [8, 5, 3, 2, 1]
Alphabetical: ["bee", "cat", "dolphin", "elephant"]
By length: ["bee", "cat", "dolphin", "elephant"]自分で試してみよう
extends Node
# ここに比較関数 by_length() を記述する
func _ready():
var numbers: Array[int] = []
for text in OS.read_string_from_stdin().split(" ", false):
numbers.append(int(text))
var words := Array(OS.read_string_from_stdin().split(" ", false))
# 配列をソートし、4 行を出力する
pass
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
ロジックとフローのすべてのレッスン
自分で練習してみよう: GDScriptオンラインコンパイラ