見出し画像

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()は元のリストの順番を変えてしまうので、順番を保持したい場合は新たな変数に代入する等してください。


ここまでお読みいただきありがとうございました!


参考


この記事が気に入ったらサポートをしてみませんか?