JavaScript_localeCompare()でsort()をスマートに定義する #295日目
【一言日記】
色々と調整が難しいタイミングで、少しずつ更新頻度が下がってきました。今は忍耐の時期。少しずつでも進めます。
JavaScriptのsort()については以前もまとめましたが、それをよりスマートに実装する方法についてメモしたいと思います。
まず、sort()は配列に対して使用可能なメソッドで、配列の要素を2つずつ比較していき、順番を決めることができます。
何も定義せずに使用すると、配列の要素を文字列として扱い、UTF-16コードの値を昇順に並べ替えます。
const list = ['Taro', 'Jiro', 'Saburo'];
list.sort();
console.log(list);
# 結果
["Jiro","Saburo","Taro"]
この場合、数字も文字列として認識されるため、意図通りにならない可能性があります。
const list = [3, 1, 21];
list.sort();
console.log(list);
# 結果
[1,21,3]
そこで、sort()には自分で並び順を定義する方法が用意されています。引数に(a, b)を渡し、大小関係に応じてreturnを出し分けます。1などの「0より大きい数字」が戻ると、aとbのうちbが先に来ます。-1などの「0より小さい数字」が戻ると、aとbのうちaが先にきます。0の場合はそのままになります。
const test = [1, 30, 25, 40];
test.sort((a, b) => {
if (a > b) {
return 1;
} else if (a < b) {
return -1;
} else {
return 0;
}
});
console.log(test)
// 出力結果
[ 1, 25, 30, 40 ]
もし並べ替えたい配列が数字の場合、上記はもっとシンプルに書けます。直接引き算して大小比較すればOKです。
const test = [1, 30, 25, 40];
test.sort((a, b) => {return a - b}); # aが小さければ負(aが先)、aが大きければ正(aが後)
// 出力結果
[ 1, 25, 30, 40 ]
さて、いよいよlocaleCompare()です。
localeCompare()はStringオブジェクトのメソッド、つまり文字列に対して使うことができます。日付などにも使えます。
localeCompare()は、第一引数と比べて並び順が前に来るか後ろに来るかを判定します。並び順が前に来るなら負の数値を、後ろに来るなら正の数値を返し、同じなら 0 を返します。
つまり、sort()のために用意されたような関数です。基本文法は以下です。
配列.sort((a, b) => {
// 'en'以降はオプション。
// 第二引数はロケールで、'en'は英語。
// 第三引数は比較アルゴリズムのオプションで、ここでは比較対象の値を数字と見做すことを指している
return a.localeCompare(b, 'en', { numeric: true });
});
例えば以下のように使えます。先に日付で昇順にし、同日なら体重で昇順にしてみます。
const list = [
{ name: 'Hanako', date: '2021-12-03', weight: 54.8 },
{ name: 'Taro', date: '2021-12-02', weight: 78.1 },
{ name: 'Hanako', date: '2021-12-04', weight: 54.4 }
{ name: 'Hanako', date: '2021-12-02', weight: 54.2 },
{ name: 'Taro', date: '2021-12-04', weight: 77.2 },
];
list.sort((a, b) => {
const result: number = a.date.localeCompare(b.date);
return result !=0 ? result : a.weight - b.weight;
});
# 結果
[
{ name: 'Hanako', date: '2021-12-02', weight: 54.2 },
{ name: 'Taro', date: '2021-12-02', weight: 78.1 },
{ name: 'Hanako', date: '2021-12-03', weight: 54.8 },
{ name: 'Hanako', date: '2021-12-04', weight: 54.4 }
{ name: 'Taro', date: '2021-12-04', weight: 77.2 },
]
resultが0以外ならresultの値で並び替え、0ならweightで並び変わります。
ちなみに忘れがちですが、sort()は元のリストの順番を変えてしまうので、順番を保持したい場合は新たな変数に代入する等してください。
ここまでお読みいただきありがとうございました!
参考
この記事が気に入ったらサポートをしてみませんか?