JavaScriptで日付が新しい順・古い順, あいうえお順のSort処理を実装してみた!
こんにちは、AIQ株式会社のフロントエンドエンジニアのまさぴょんです!
今回は、JavaScriptで日付が新しい順・古い順, あいうえお順のSort処理を実装する機会があったので、その知見と学びについて共有します。
前提: 基本のSort処理Logicを振り返る
本題の日付が新しい順(降順)・古い順(昇順), あいうえお順のSort処理の実装についての解説に入る前に、基本のSort処理Logicを振り返りましょう。
昇順と降順に関しては、以前にこちらの記事で説明しています。
JavaScriptで配列の要素を昇順や降順での並び替え・Sort処理するには、次のどちらかのメソッドを使用すればOKです。
-
Array.prototype.sort()
- 指定配列をSortします(破壊的変更)
-
Array.prototype.toSorted()
- 指定配列のコピーをSortして実行結果として、返却します。
sortメソッドで指定配列を昇順または降順でSortする(破壊的変更)
Array.prototype.sort()
で指定配列を昇順または降順でSortすることができます。
const numberList = [1, 30, 4, 21, 100000];
/** 昇順・Sort */
const ascNumberList = numberList.sort((a, b) => a - b);
console.log("ascNumberList", ascNumberList); // ascNumberList (5) [1, 4, 21, 30, 100000]
console.log("numberList(元配列)", numberList); // numberList(元配列) (5) [1, 4, 21, 30, 100000]
/** 降順・Sort */
const descNumberList = numberList.sort((a, b) => b - a);
console.log("descNumberList", descNumberList); // descNumberList (5) [100000, 30, 21, 4, 1]
console.log("numberList(元配列)", numberList); // numberList(元配列) (5) [100000, 30, 21, 4, 1]
toSortedメソッドで指定配列のコピーを昇順または降順でSortする
Array.prototype.toSorted()
で、指定配列のコピーをSortすることができます。
const numberList2 = [1, 30, 4, 21, 100000];
/** 昇順・Sort */
const ascNumberList2 = numberList2.toSorted((a, b) => a - b);
/** 降順・Sort */
const descNumberList2 = numberList2.toSorted((a, b) => b - a);
console.log("numberList2(元配列)", numberList2); // numberList2(元配列) (5) [1, 30, 4, 21, 100000]
console.log("ascNumberList2", ascNumberList2); // ascNumberList2 (5) [1, 4, 21, 30, 100000]
console.log("descNumberList2", descNumberList2); // descNumberList2 (5) [100000, 30, 21, 4, 1]
ここら辺の処理は、私の個人Tech Blogの記事内容から引用しています。
JavaScriptで日付が新しい順・古い順のSort処理を実装する
日付が新しい順・古い順のSort処理を実装する方法を考えていきますが、
その前に、日付の昇順(asc)と降順(desc)を比較すると次のようになります。
日付の古い順(昇順・asc) | 日付の新しい順(降順・desc) |
---|---|
1995/12/12 | 2100/12/12 |
2050/12/12 | 2050/12/12 |
2100/12/12 | 1995/12/12 |
日付の古い順が昇順・asc であり、日付の新しい順が、降順・descである点に注意しましょう。
それでは、実装を見ていきます。
日付が新しい順(降順・desc)のSort処理を実装する
日付が新しい順(降順・desc)のSort処理は、次のようにして、実装することができます。
/**
* NOTE: 日付の新しい順(降順) で Sortする
* @param {string} a - 日付
* @param {string} b - 日付
* @return {number}
*/
function descTimeSort(a, b) {
return a < b ? 1 : -1;
}
/** 文字列の日付リスト */
let dateList = [
"2018/08/15",
"2018/01/05",
"2018/12/10",
"2018/05/01",
"2018/12/01",
"2018/11/01",
"2019/01/01",
"2019/02/01",
];
// 日付の新しい順(降順・desc)
dateList.sort((a, b) => descTimeSort(a, b));
console.log("dateList Ver. 日付の新しい順(降順)", dateList);
// dateList Ver. 日付の新しい順(降順) (8) ['2019/02/01', '2019/01/01', '2018/12/10', '2018/12/01', '2018/11/01', '2018/08/15', '2018/05/01', '2018/01/05']
/** Date Object の日付リスト */
const dateTimeList = [
{ id: 1, date: new Date(2020, 2, 22) },
{ id: 2, date: new Date(2020, 1, 1) },
{ id: 3, date: new Date(2019, 7, 28) },
{ id: 4, date: new Date(2080, 1, 1) },
{ id: 5, date: new Date(2100, 12, 12) },
];
// 日付の新しい順(降順・desc)
dateTimeList.sort((a, b) => descTimeSort(a.date, b.date));
console.log("dateTimeList Ver. 日付の新しい順(降順)", dateTimeList);
// [ 出力結果 ]
// dateTimeList Ver. 日付の新しい順(降順)
// 0: {id: 5, date: Wed Jan 12 2101 00:00:00 GMT+0900 (日本標準時)}
// 1: {id: 4, date: Thu Feb 01 2080 00:00:00 GMT+0900 (日本標準時)}
// 2: {id: 1, date: Sun Mar 22 2020 00:00:00 GMT+0900 (日本標準時)}
// 3: {id: 2, date: Sat Feb 01 2020 00:00:00 GMT+0900 (日本標準時)}
// 4: {id: 3, date: Wed Aug 28 2019 00:00:00 GMT+0900 (日本標準時)}
日付が古い順(昇順・asc)のSort処理を実装する
日付が古い順(昇順・asc)のSort処理は、次のようにして、実装することができます。
/**
* NOTE: 日付の古い順(昇順) で Sortする
* @param {string} a - 日付
* @param {string} b - 日付
* @return {number}
*/
function ascTimeSort(a, b) {
return a > b ? 1 : -1;
}
// 日付の古い順(昇順)
dateList.sort((a, b) => ascTimeSort(a, b));
console.log("dateList Ver. 日付の古い順(昇順)", dateList);
// dateList Ver. 日付の古い順(昇順) (8) ['2018/01/05', '2018/05/01', '2018/08/15', '2018/11/01', '2018/12/01', '2018/12/10', '2019/01/01', '2019/02/01']
/** Date Object の日付リスト */
const dateTimeList2 = [
{ id: 1, date: new Date(2020, 2, 22) },
{ id: 2, date: new Date(2020, 1, 1) },
{ id: 3, date: new Date(2019, 7, 28) },
{ id: 4, date: new Date(2080, 1, 1) },
{ id: 5, date: new Date(2100, 12, 12) },
];
// 日付の古い順(昇順)
dateTimeList2.sort((a, b) => ascTimeSort(a.date, b.date));
console.log("dateTimeList2 Ver. 日付の古い順(昇順)", dateTimeList2);
// [ 出力結果 ]
// dateTimeList2 Ver. 日付の古い順(昇順)
// 0: {id: 3, date: Wed Aug 28 2019 00:00:00 GMT+0900 (日本標準時)}
// 1: {id: 2, date: Sat Feb 01 2020 00:00:00 GMT+0900 (日本標準時)}
// 2: {id: 1, date: Sun Mar 22 2020 00:00:00 GMT+0900 (日本標準時)}
// 3: {id: 4, date: Thu Feb 01 2080 00:00:00 GMT+0900 (日本標準時)}
// 4: {id: 5, date: Wed Jan 12 2101 00:00:00 GMT+0900 (日本標準時)}
最新登録日(新しい順)や古い順SortするLogicを構築
先述のLogicをベースに、今回実装することとなった、日付が新しい順・古い順で送付先(住所)の情報を並び替えるSampleCodeは次のようになります。
/** 1. 並び替えたい 対象の DataSet (送付先リスト) */
const addressList = [
{
user_id: "1000020339",
city: "渋谷区",
full_name: "ロボ ロボたま",
address_line1: "",
address_line2: null,
building: "",
district: "ハチ公前",
first_name: "ロボたま",
last_name: "ロボ",
input_type: 2,
post_code: "111-0078",
phone_number: "1111111111",
user_address_id: 1000020357,
province: "東京都",
create_time: "2024-01-24T08:00:33.472Z",
update_time: null,
default: false,
},
{
user_id: "1000020339",
city: "桐生市",
full_name: "白桃 さん",
address_line1: "メゾン白桃",
address_line2: null,
building: "",
district: "広沢町",
first_name: "さん",
last_name: "白桃",
input_type: 2,
post_code: "111-0075",
phone_number: "1111111111",
user_address_id: 1000020358,
province: "群馬県",
create_time: "2024-01-24T08:07:23.560Z",
update_time: null,
default: true,
},
{
user_id: "1000020339",
city: "名古屋市",
full_name: "もも たん",
address_line1: "桃玉ハウス",
address_line2: null,
building: "",
district: "中央区",
first_name: "たん",
last_name: "もも",
input_type: 2,
post_code: "111-0077",
phone_number: "1111111111",
user_address_id: 1000020359,
province: "愛知県",
create_time: "2024-01-26T08:07:23.560Z",
update_time: null,
default: true,
},
{
user_id: "1000020339",
city: "福岡市",
full_name: "ぴゅぴゅ丸",
address_line1: "ぴゅぴゅ丸ハウス",
address_line2: null,
building: "",
district: "ぴゅぴゅ丸",
first_name: "丸",
last_name: "ぴゅぴゅ",
input_type: 2,
post_code: "111-0077",
phone_number: "1111111111",
user_address_id: 1000020360,
province: "福岡県",
create_time: "2024-01-26T08:12:23.560Z",
update_time: null,
default: true,
},
{
user_id: "1000020339",
city: "さいたま市",
full_name: "ぷる たま",
address_line1: "",
address_line2: null,
building: "",
district: "東大宮",
first_name: "たま",
last_name: "ぷる",
input_type: 2,
post_code: "111-0088",
phone_number: "1111111111",
user_address_id: 1000020365,
province: "埼玉県",
create_time: "2024-01-25T09:30:47.730Z",
update_time: null,
default: false,
},
];
/** 最新登録順(降順)で、Sortされた配列 */
const timeSortListAsc = [];
// 2. addressList の create_time を基準に「最新登録順(降順)」で Sort して timeSortList に pushする
addressList
.sort((a, b) => {
return a.create_time > b.create_time ? -1 : 1;
})
.forEach((address) => {
timeSortListAsc.push(address);
});
console.log("最新登録順(降順)", timeSortListAsc);
console.log("--------------------------");
/** 古い順(昇順) で、Sortされた配列 */
const timeSortListDesc = [];
// 3. 古い順(昇順): addressList の create_time を基準に「古い順(昇順)」で Sort して timeSortList に pushする
addressList
.sort((a, b) => {
return a.create_time < b.create_time ? -1 : 1;
})
.forEach((address) => {
timeSortListDesc.push(address);
});
console.log("古い順(昇順)", timeSortListDesc);
JavaScriptであいうえお順のSort処理を実装する
あいうえお順のSort処理を実装する方法を考えていきます。
次のように、日本語に対して、Array.prototype.sort()
を使用すると、漢字など一部でSort処理があいうえお順にならない事象が発生します。
const array = ["う", "い", "あ", "ウ", "イ", "ア", "宇", "井", "亜", "a", "i", "u"];
array.sort();
console.log(array);
// 出力結果 => [a,i,u,あ,い,う,ア,イ,ウ,井,亜,宇]
このような事象が起こるため、日本語の50音順にソートしたい場合はlocaleCompare
やIntl.Collator
を利用します。
const array = ["う", "い", "あ", "ウ", "イ", "ア", "宇", "井", "亜", "a", "i", "u"];
array.sort((a, b) => {
return a.localeCompare(b, 'ja');
});
console.log(array);
// 出力結果 => [a,i,u,あ,ア,い,イ,う,ウ,亜,井,宇]
今回、実装した、より具体的なSampleCodeでは、読み方が複数ある漢字であることも考慮して、
漢字の読み仮名(ひらがな)をDataSetに追加する対応を実施しています。
読み仮名(ひらがな)を用意しておけば、正しいあいうえお順のSort処理を実行することができます。
/** 1. 都道府県 DataSet を用意する (name: 漢字, ruby: ひらがな) */
const proviceItems = [
{ name: "北海道", ruby: "ほっかいどう" },
{ name: "青森県", ruby: "あおもりけん" },
{ name: "岩手県", ruby: "いわてけん" },
{ name: "宮城県", ruby: "みやぎけん" },
{ name: "秋田県", ruby: "あきたけん" },
{ name: "山形県", ruby: "やまがたけん" },
{ name: "福島県", ruby: "ふくしまけん" },
{ name: "茨城県", ruby: "いばらきけん" },
{ name: "栃木県", ruby: "とちぎけん" },
{ name: "群馬県", ruby: "ぐんまけん" },
{ name: "埼玉県", ruby: "さいたまけん" },
{ name: "千葉県", ruby: "ちばけん" },
{ name: "東京都", ruby: "とうきょうと" },
{ name: "神奈川県", ruby: "かながわけん" },
{ name: "新潟県", ruby: "にいがたけん" },
{ name: "富山県", ruby: "とやまけん" },
{ name: "石川県", ruby: "いしかわけん" },
{ name: "福井県", ruby: "ふくいけん" },
{ name: "山梨県", ruby: "やまなしけん" },
{ name: "長野県", ruby: "ながのけん" },
{ name: "岐阜県", ruby: "ぎふけん" },
{ name: "静岡県", ruby: "しずおかけん" },
{ name: "愛知県", ruby: "あいちけん" },
{ name: "三重県", ruby: "みえけん" },
{ name: "滋賀県", ruby: "しがけん" },
{ name: "京都府", ruby: "きょうとふ" },
{ name: "大阪府", ruby: "おおさかふ" },
{ name: "兵庫県", ruby: "ひょうごけん" },
{ name: "奈良県", ruby: "ならけん" },
{ name: "和歌山県", ruby: "わかやまけん" },
{ name: "鳥取県", ruby: "とっとりけん" },
{ name: "島根県", ruby: "しまねけん" },
{ name: "岡山県", ruby: "おかやまけん" },
{ name: "広島県", ruby: "ひろしまけん" },
{ name: "山口県", ruby: "やまぐちけん" },
{ name: "徳島県", ruby: "とくしまけん" },
{ name: "香川県", ruby: "かがわけん" },
{ name: "愛媛県", ruby: "えひめけん" },
{ name: "高知県", ruby: "こうちけん" },
{ name: "福岡県", ruby: "ふくおかけん" },
{ name: "佐賀県", ruby: "さがけん" },
{ name: "長崎県", ruby: "ながさきけん" },
{ name: "熊本県", ruby: "くまもとけん" },
{ name: "大分県", ruby: "おおいたけん" },
{ name: "宮崎県", ruby: "みやざきけん" },
{ name: "鹿児島県", ruby: "かごしまけん" },
{ name: "沖縄県", ruby: "おきなわけん" },
];
// 2. 事前に、都道府県の読み仮名(ruby: ひらがな) を基準に あいうえお順 で Sort する
proviceItems.sort((a, b) => a.ruby.localeCompare(b.ruby), "ja");
console.log("proviceItems", proviceItems);
/** 3. 並び替えたい 対象の DataSet (送付先リスト) */
const addressList = [
{
user_id: "1000020339",
city: "渋谷区",
full_name: "ロボ ロボたま",
address_line1: "",
address_line2: null,
building: "",
district: "ハチ公前",
first_name: "ロボたま",
last_name: "ロボ",
input_type: 2,
post_code: "111-0078",
phone_number: "1111111111",
user_address_id: 1000020357,
province: "東京都",
create_time: "2024-01-24T08:00:33.472Z",
update_time: null,
default: false,
},
{
user_id: "1000020339",
city: "桐生市",
full_name: "白桃 さん",
address_line1: "メゾン白桃",
address_line2: null,
building: "",
district: "広沢町",
first_name: "さん",
last_name: "白桃",
input_type: 2,
post_code: "111-0075",
phone_number: "1111111111",
user_address_id: 1000020358,
province: "群馬県",
create_time: "2024-01-24T08:07:23.560Z",
update_time: null,
default: true,
},
{
user_id: "1000020339",
city: "名古屋市",
full_name: "もも たん",
address_line1: "桃玉ハウス",
address_line2: null,
building: "",
district: "中央区",
first_name: "たん",
last_name: "もも",
input_type: 2,
post_code: "111-0077",
phone_number: "1111111111",
user_address_id: 1000020359,
province: "愛知県",
create_time: "2024-01-26T08:07:23.560Z",
update_time: null,
default: true,
},
{
user_id: "1000020339",
city: "福岡市",
full_name: "ぴゅぴゅ丸",
address_line1: "ぴゅぴゅ丸ハウス",
address_line2: null,
building: "",
district: "ぴゅぴゅ丸",
first_name: "丸",
last_name: "ぴゅぴゅ",
input_type: 2,
post_code: "111-0077",
phone_number: "1111111111",
user_address_id: 1000020360,
province: "福岡県",
create_time: "2024-01-26T08:12:23.560Z",
update_time: null,
default: true,
},
{
user_id: "1000020339",
city: "さいたま市",
full_name: "ぷる たま",
address_line1: "",
address_line2: null,
building: "",
district: "東大宮",
first_name: "たま",
last_name: "ぷる",
input_type: 2,
post_code: "111-0088",
phone_number: "1111111111",
user_address_id: 1000020365,
province: "埼玉県",
create_time: "2024-01-25T09:30:47.730Z",
update_time: null,
default: false,
},
];
// 都道府県 を基準に あいうえお順 で Sort する
addressList.sort((addressA, addressB) => {
/** 都道府県名 A */
const provinceA = addressA.province;
console.log("都道府県 Part A", provinceA);
/** 都道府県名 B */
const provinceB = addressB.province;
console.log("都道府県 Part B", provinceB);
/** 都道府県名 A の index(あいうえお順で並んでいる番号) */
const orderindexA = proviceItems.findIndex(
(provice) => provice.name === provinceA
);
/** 都道府県名 B の index(あいうえお順で並んでいる番号) */
const orderindexB = proviceItems.findIndex(
(provice) => provice.name === provinceB
);
console.log("あいうえお順で並んだ際の順序(番号) Part A", orderindexA);
console.log("あいうえお順で並んだ際の順序(番号) Part B", orderindexB);
// 昇順ソート(あいうえお順)
return orderindexA - orderindexB;
});
console.log("addressList", addressList);
Code中のコメントに処理のポイントは記述していますが、まとめると次のとおりです。
まとめ
機能開発にて、日付が新しい順・古い順, あいうえお順のSort処理の方法について学べてよかったです。
ぜひご活用してみてください。
個人で、Blogもやっています、よかったら見てみてください。
注意事項
この記事は、AIQ 株式会社の社員による個人の見解であり、所属する組織の公式見解ではありません。
求む、冒険者!
AIQ株式会社では、一緒に働いてくれるエンジニアを絶賛、募集しております🐱🐹✨
詳しくは、Wantedly (https://www.wantedly.com/companies/aiqlab)を見てみてください。
参考・引用
AIQ 株式会社 に所属するエンジニアが技術情報をお届けします。 ※ AIQ 株式会社 社員による個人の見解であり、所属する組織の公式見解ではありません。 Wantedly: wantedly.com/companies/aiqlab
Discussion