JavaScriptで配列を年と月の順に並べ替える方法
はじめに
JavaScriptで開発をしていると、オブジェクトを格納した配列を複数の条件で並べ替えたい場面によく出会います。その代表例が、「年(year)」と「月(month)」を持つデータを、年の昇順でソートし、同じ年が重なる場合は月の順番(1月→2月→3月…)で並べ替えるというケースです。
本記事では、次のような配列を例に、この並べ替えを実現する方法をわかりやすく解説します。
const arr = [{
year: 2020,
month: 'January'
}, {
year: 2017,
month: 'March'
}, {
year: 2010,
month: 'January'
}, {
year: 2010,
month: 'December'
}, {
year: 2020,
month: 'April'
}, {
year: 2017,
month: 'August'
}, {
year: 2010,
month: 'February'
}, {
year: 2020,
month: 'October'
}, {
year: 2017,
month: 'June'
}]要件の整理
この配列に対して、以下の2つのルールで並べ替えを行います。
- 第1条件: year プロパティを基準に昇順(古い年から新しい年へ)でソートする
- 第2条件: year が同じオブジェクト同士については、month プロパティを基準に暦の順(January → February → March …)でソートする
月は文字列として格納されているため、単純な大小比較はできません。そこで、あらかじめ定義した月名の配列を活用し、文字列をインデックス番号に変換して比較するのがポイントです。
実装コード
それでは、実際のコードを見てみましょう。完全なサンプルコードは以下の通りです。
const arr = [{
year: 2020,
month: 'January'
}, {
year: 2017,
month: 'March'
}, {
year: 2010,
month: 'January'
}, {
year: 2010,
month: 'December'
}, {
year: 2020,
month: 'April'
}, {
year: 2017,
month: 'August'
}, {
year: 2010,
month: 'February'
}, {
year: 2020,
month: 'October'
}, {
year: 2017,
month: 'June'
}]
// 月名を正しい順序で並べた基準用の配列
const months = ['January', 'February', 'March', 'April', 'May', 'June',
'July', 'August', 'September', 'October', 'November', 'December'];
// 比較関数:まず年を比較し、同じ年なら月を比較する
const sorter = (a, b) => {
if(a.year !== b.year){
return a.year - b.year;
}else{
return months.indexOf(a.month) - months.indexOf(b.month);
};
};
arr.sort(sorter);
console.log(arr);コードの解説
このソート処理の仕組みを順番に見ていきましょう。
1. 基準となる月名配列を用意する
months 配列には、1月から12月までの英語の月名を暦の順に格納しています。これにより、indexOf() を使えば「'January' → 0」「'December' → 11」というように、月名を数値に変換して比較できるようになります。
2. 比較関数 sorter のロジック
Array.prototype.sort() に渡す比較関数では、戻り値が負の数なら a が前、正の数なら b が前に配置されます。
- 2つのオブジェクトの year が異なる場合は、
a.year - b.yearを返して年の昇順に並べます。 - year が同じ場合には、
months.indexOf()の差を返すことで、同じ年内のオブジェクトが月の順序どおりに並ぶようにしています。
実行結果
上記のコードを実行すると、コンソールには次のように出力されます。
[
{ year: 2010, month: 'January' },
{ year: 2010, month: 'February' },
{ year: 2010, month: 'December' },
{ year: 2017, month: 'March' },
{ year: 2017, month: 'June' },
{ year: 2017, month: 'August' },
{ year: 2020, month: 'January' },
{ year: 2020, month: 'April' },
{ year: 2020, month: 'October' }
]結果を見ると、まず年が 2010 → 2017 → 2020 の順に昇順で並んでおり、さらに同じ年内では January → February → December という具合に、月が暦の順にきちんと整列していることが確認できます。
まとめ
複数のキーでオブジェクト配列をソートしたい場合は、比較関数の中で優先度の高い条件から順に判定し、条件が一致したら次の条件へフォールバックするのが基本パターンです。今回のように文字列データを扱う場合は、対応表(ここでは months 配列)と indexOf() を組み合わせることで、簡単かつ確実に順序比較が実現できます。日付データが Date オブジェクトとして保持できる場合は、getTime() や valueOf() を使って直接比較することも可能なので、用途に応じて使い分けるとよいでしょう。
-
JavaScriptのArray.prototype.sort()メソッドの使い方をサンプルコードで解説
Array.prototype.sort()は、JavaScriptで配列の要素を並べ替えるための組み込みメソッドです。アルファベット順・数値順といった並び方に加えて、昇順・降順も自由に指定でき、配列操作の中でも特に使用頻度の高いメソッドの一つです。 ただし重要なポイントとして、sort()メソッドはデフォルトではすべての要素を文字列に変換してから比較します。そのため、数値の配列を意図したとおりに並べ替えたい場合は、比較関数を引数として渡す必要があります。 以下は、Array.prototype.sort()メソッドの基本的な使い方を示すサンプルコードです。 サンプルコード <!DOC
-
JavaScriptでオブジェクト配列をindexプロパティの値に基づいて並べ替える方法
はじめにJavaScriptでは、オブジェクトが格納された配列を特定のプロパティの値に基づいて並べ替えたい場面がよくあります。本記事では、各オブジェクトが持つ index プロパティの値を基準に配列を昇順にソートし、その結果を文字列の配列へ変換する方法を解説します。対象となるデータ例として、次のようなオブジェクトの配列を想定します。const arr = [ { name: d, index: 3 }, { name: c, index: 2 }, { name: a,