配列の要素ではなく、配列それ自体の大小比較をしてみる
JavaScript
[1, 11, 3] > [1, 2, 4]
false
JSで配列を順序比較すると文字列に変換されて辞書順比較を行うためfalseとなる。順序比較するとまずToPrimitiveが呼ばれるがArrayはToPrimitiveを実装してない。その場合はvalueOfが呼ばれ、ArrayのvalueOfは自分自身を返す。valueOfがObjectを返した場合はtoStringを呼ぶ、という仕様らしい。
Ruby
[1, 11, 3] > [1, 2, 4]
例外がスローされる。Rubyは演算子もメソッドであり、Arrayは > メソッドを実装していないのでNoMethodError。
Java
public class Hoge { public static void main(String[] args) { int[] x = new int[1]; int[] y = new int[2]; System.out.println(x > y); } }
コンパイルエラー、エラー: 二項演算子'>'のオペランド型が不正です
Golang:
package main import "fmt" func main() { a := []int{1, 11, 3} b := []int{1, 2, 4} fmt.Println(a > b) }
コンパイルエラー、invalid operation: a > b (operator > not defined on slice)
Swift
let a = [1, 11, 3] let b = [1, 2, 4] print(a > b)
コンパイルエラー、error: binary operator '>' cannot be applied to two '[Int]' operands
Rust
fn main() { let a = [1, 11, 3]; let b = [1, 2, 4]; println!("{}", a > b); }
true
どうやら要素を先頭から順番に比較しているようだ。2つのスライスの長さが異なるとコンパイルエラーになる。vecは長さが違っても比較可能。
Python
>>> [1, 11, 3] > [1, 2, 4] True
Rustと同じ結果
PHP
<?php $a = [1,11,3]; $b = [1,2,4]; echo $a > $b; ?>
1
こちらもRustと同じ結果に
まとめ
言語 | 結果 |
---|---|
JavaScript | toStringして比較 |
Ruby | 実行時エラー |
Java | コンパイルエラー |
Go | コンパイルエラー |
Swift | コンパイルエラー |
Rust | 要素の先頭から比較 |
Python | 要素の先頭から比較 |
PHP | 要素の先頭から比較 |
RustでSHAハッシュ値の大小比較をしたくて、文字列化せずバイト配列のまま比較できないかなー?と思って試したらできてしまったので、他の言語も調べてみた次第
追記
Qiitaに転載した