よくあるCompareという関数の理解の方法について

何個かのプログラミング言語触ってると、よくcompareという名前の比較関数を目にする。 この記事内では、goの文法で書くが、大抵の言語で当てはまる考え方だと思う。

// if a == b then 0
// if a < b then negative integer
// if a > b then positve integer
func Compare(a, b int) int {
    return a - b
}

このような実装で、int同士の大小比較をする比較関数が書ける。 この記事で書きたいのは、このような比較関数を使うとき、比較関数から返される数値を扱うためのわかりやすい理解の仕方について。

実際に上で書いた比較関数を使うときには、このようにする。

if Compare(a, b) == 0 {
    // aとbの大小関係が等しいときの処理
}
if Compare(a, b) < 0 {
    // aがbより小さいときの処理
}
if Compare(a, b) > 0 {
    // aがbより大きいときの処理
}

個人的ポイントは、比較関数を扱うときは常に0との比較をすること。 なぜかというと、形式的に上記if文を展開することができるから。 注釈を加えて再度if文を記述してみると、以下のようになる。

if Compare(a, b) == 0 { // a == 0
    // aとbの大小関係が等しいときの処理
}
if Compare(a, b) < 0 { // a < b
    // aがbより小さいときの処理
}
if Compare(a, b) > 0 { // a > b
    // aがbより大きいときの処理
}

非常にわかりやすく、覚えやすくなりませんかね。 なぜこうなるか、という理屈の話をすると、数式で見ると明らかです。

a - b = 0
a - b < 0
a - b > 0

単にbを右辺に移動させるだけっていうね。

ここまで書いた話は、数値比較だろうと文字列比較だろうと変わりなく使えます。 比較関数の返り値と0以外を比較したときには、当てはまらない場合があるため、基本戦略として比較関数の返り値は0と比較しておくと安心です。

以下余談。

C言語の比較関数などは、ここまで書いた話と違っている場合があり、具体的には比較関数の返り値の意味が正負反転することがあります。 こういうものは、大抵が言語の文化に合わせてあることが多いため、対象とする言語が正論理なのか負論理なのか、と合わせて覚えるとわかりやすいと思います。