SortBy

# Stably sort `Array` using `Less` where `Less` succeeding indicates `Left` should precede `Right`
SortBy<native><public>((Array:[]t, Less:type {_(:t, :t)<computes><decides>:void}) where t:type)<computes>:[]t

UnrealEngine.digestにはSortByという関数が用意されています。今回はこの関数の使い方を紹介しようと思います。

比較関数の作成

GreaterThan(X:int, Y:int)<computes><decides>:void=
    X > Y

SortBy関数の引数に渡すようの別の関数を作成します。この関数は

  • 同じ型の引数を2つ持つ
  • <computes><decides>のエフェクト指定子を持つ
  • 戻り値はvoid

の条件を満たしている必要があります。今回は試しにint型を比較する関数を作ってみます。

失敗関数であるため、関数内に直接条件式を書き込むことができます。通常の使い方であれば、if内でこの関数を呼び出すと「XがYよりも大きい場合はif内の処理が実行され、小さい場合はelseの処理が実行する」というものになります。

SortByではこの関数を基準にソートを行います。

SortByで使用

Numbers := array{5, 2, 3, 8, 22, 30, 1, 43}
Result := SortBy(Numbers, GreaterThan)
# {43, 30, 22, 8, 5, 3, 2, 1}で並び替えされる

SortByを使用する場合、まずは第一引数にソート対象となる値の入った配列を、第二引数に比較関数を入れます。すると、戻り値として比較関数に基づいてソートされた配列が返ってきます。

結果としての配列は「比較関数が成功するものを先頭に押し上げ、失敗したものは後ろになる」という内部の処理が行われています。そのため、GreaterThan内の比較の条件を「>より大きい」から「<より小さい」に変更すれば、配列の結果は小さいもの順になるはずです。

マップ型を使用

var PointsPerAgent:[agent]int = map{}

Array:[]tuple(agent, int) = for(Key -> Value : PointsPerAgent){(Key, Value)}
Result := SortBy(Array, GreaterThan)

GreaterThan(X:tuple(agent, int), Y:tuple(agent, int))<computes><decides>:void=
    X(1) > Y(1)

マップ用のSortByは用意されていないため、map型を使用する場合は一度配列に変換するような処理をする必要があります。

個人的にオススメなのは、マップのキーと値をtupleにした配列にすることです。こうすると、「誰が」という情報と「現在の値」の両方の情報を保持したままソートすることができます。リザルト画面を作る際などにも便利なのでぜひ活用してみましょう。