もやもやエンジニア

IT系のネタで思ったことや技術系のネタを備忘録的に綴っていきます。フロント率高め。

JavaScriptで配列をソートする

最近ネタがないのでJavaScriptの小ネタでも。

配列を並び替えるメソッドで[sort]が用意されています。

var ARY = ['ichi','ni','san','shi','go'];
ARY = ARY.sort();
console.log(ARY);

このようなコードを実行すると以下のように出力されます。

> ["go", "ichi", "ni", "san", "shi"]

sortによって配列の中身がアルファベットの昇順で並び替えられていますね。

では数値でやるとどうなるでしょうか。

var ARY = [5,1,3,4,2];
ARY = ARY.sort();
console.log(ARY);

> [1, 2, 3, 4, 5]

値の昇順になりました・・・・が、これには罠があります。以下のようにするとどうなるでしょうか。

var ARY = [5,10,3,14,2];
ARY = ARY.sort();
console.log(ARY);

正解はこちら

> [10, 14, 2, 3, 5]

数値の昇順になるかと思いきや、10と14が先に来ています。これはsortが数値の比較をしておらず、文字列に変換して辞書順で比較しているためです。

そんなときはsortを拡張しようーという訳で、こちらの仕様を見て下さい。

array.sort(compareFunction);

compareFunction
ソート順を定義する関数を指定します。省略された場合、配列は各要素の文字列比較に基づき辞書順にソートされます。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

ということで、先ほどのコードを期待通りに動かすようにしたものがこちら

var ARY = [5,10,3,14,2];
ARY = ARY.sort(function(a,b){
    return a - b;
});
console.log(ARY);
> [2, 3, 5, 10, 14]

比較条件を設定した無名関数を引数で渡すことでsortの内部処理を拡張できます。
拡張する関数は引数として配列内の要素を二つ(aとb)受け取り、返却値により配列の添字を入れ替えます。

①返却値が0より小さい場合はa を b より小さい添字にソートする
②返却値が0の場合はお互いに関しては何もしない
③返却値が0より大きい場合はb を a より小さい添字にソートする

配列の中身がオブジェクトだったりした場合でも使えるので色々応用できますね〜

プロになるためのJavaScript入門 ~node.js、Backbone.js、HTML5、jQuery-Mobile (Software Design plus)

プロになるためのJavaScript入門 ~node.js、Backbone.js、HTML5、jQuery-Mobile (Software Design plus)