sort!() や sort() において,昇順とか降順は数値の大小とか文字列ならば辞書順(これも大小ではあるが)による。
しかし,ある場合には単なる辞書順ではなく別の基準で並べ替えなければならないことがある。
このような場合には,sort!() や sort() の引数の lt で関数を指定する。
その関数は引数を 2 つとり,a が b より前(昇順で b は a より後)ならば true,そうでなければ false を返す。デフォルトでは lt = isless である。isless も 2 つの引数をとり,例示するような結果を返す。
isless(1, 4) # true
isless("a", "abcde") # true
isless(π, ℯ) # π = 3.1415926535897...,ℯ = 2.7182818284590... ゆえ false
たとえば,年号が
nengou = ["明治", "大正", "昭和", "平成", "令和"]
のとき,普通にソートすると
sort(nengou)
#=
5-element Vector{String}:
"令和"
"大正"
"平成"
"明治"
"昭和"
=#
になってしまう。
年号のデータを「"明治", "大正", "昭和", "平成", "令和"」の順でソートしたいときは以下のような関数を定義する。
function compare(a, b)
rank(nengou) = indexin([nengou], ["明治", "大正", "昭和", "平成", "令和"])[1]
return rank(a) <= rank(b)
end
そのうえで,
sort(nengou, lt=compare)
とすれば,以下の結果になる。
#=
5-element Vector{String}:
"明治"
"大正"
"昭和"
"平成"
"令和"
=#
これは別に Julia だからということではなく,R でも Python でもそのような関数仕様になっている。
x = ["平成3", "令和2","大正7", "昭和6", "明治2", "令和1", "昭和9"]
のようなデータを年号と年の順に並べ替えるには,以下のような関数を使う。
年号を100の位,年を10, 1 の位に割り当てて一つの整数にして,大小関係を判定する関数である。
なお,データは UTF-8 なので,漢字の場合には文字数と桁数が異なるので注意が必要ではある。
function compare2(a, b)
rank(nengou) = 100indexin([nengou[1:4]], ["明治", "大正", "昭和", "平成", "令和"])[1] + parse(Int, nengou[7:end])
return rank(a) <= rank(b)
end
rank("明治23") # 123
rank("昭和5") # 305
sort(x, lt=compare2)
#=
7-element Vector{String}:
"明治2"
"大正7"
"昭和6"
"昭和9"
"平成3"
"令和1"
"令和2"
=#