JavaScript - 配列のソート 同じ値の場合は入れ替わる?
JavaScript の sort() メソッドで配列をソートする場合、 「同じ値」の順番はどうなるのでしょうか?
MDNのマニュアルには「同じ序列を持つ値の順番が保証されません」 と記載されています。
つまり、「入れ替わる場合もあるし、入れ替わらない場合もある」 ということです。
ここでは、「同じ値」を考慮した比較関数の書き方を紹介します。
「同じ値」を考慮しないソート
次のような「名前」と「ポイント」をもつオブジェクトの配列があるとします。
この配列をポイント順(昇順)でソートします。
「同じ値」は考慮していません。「同じ値」の順番が入れ替わるかどうかは不明です
// 名前、得点
var arr = [{name: "田中", point: 80},
{name: "山田", point: 90},
{name: "鈴木", point: 80},
{name: "竹田", point: 60}
];
// ソート
arr.sort(function(a, b){
if (a.point > b.point){
return 1;
} else {
return -1;
}
});
console.table(arr);
実行結果は次の通りです。
上のコードは、良く見かける比較関数の書き方で、 三項演算子を使って書いている場合もあります。
ただし、この書き方では「同じ値」の順番が入れ替わるかどうかは不明です。
「同じ値」を考慮したソート
次のコードは「同じ値」を考慮した書き方です。
「同じ値」の場合に「return 0;」としているのがポイントです。
「return 0;」とすることで「入れ替えない(順序を変更しない)」ことになります。
ですから、少なくとも「入れ替わるかどうかわからない」という不安がなくなります。
(但し、古いブラウザやマイナーなブラウザでは「return 0;」に対応していない場合があります。)
// 名前、得点
var arr = [{name: "田中", point: 80},
{name: "山田", point: 90},
{name: "鈴木", point: 80},
{name: "竹田", point: 60}
];
// ソート
arr.sort(function(a, b){
if (a.point > b.point) return 1;
if (a.point < b.point) return -1;
return 0;
});
console.table(arr);
実行結果は次の通りです。
「return 0;」とした場合に、順序を入れ替えない(変更しない)という動作は、 主要なブラウザでは対応しています。
ですから、この書き方の方がおすすめです。
まとめ
sort() メソッドは「同じ値」の順番は保証していません。
同じ場合に「return 0;」とすることで、 順序を入れ替えない(変更しない)ようにすることができます。
主要なブラウザでは「return 0;」のケースに対応しています。