裏 RjpWiki

Julia ときどき R, Python によるコンピュータプログラム,コンピュータ・サイエンス,統計学

Julia の小ネタ--037 大小順や辞書順などではない,特別な順序に基づくソート

2021年09月16日 | ブログラミング

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"
=#

コメント    この記事についてブログを書く
  • Twitterでシェアする
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする
« Julia の小ネタ--036 文字が... | トップ | Julia で積み上げ棒グラフ,... »
最新の画像もっと見る

コメントを投稿

ブログラミング」カテゴリの最新記事