🧬
【JavaScript】配列:文字列と数値が混合している要素の並び替え
以下の配列がある。奇数日がただバラバラに並んでいる文字列配列。
const odd_days = [
['1日'],['3日'],['13日'],['5日'],['9日'],['11日'],['7日'],['15日'],['17日'],
]
日付がちゃんと昇順に並ぶようにしたい。
しかしsort()
を使って並び替えても、sort()
はデフォルトでは昇順かつ文字列でソートするから、「1日」と「11日」では11日の方が先に並ぶ。
odd_days.sort()
// odd_daysの中身
// [["11日"],["13日"],["15日"],["17日"],["1日"],["3日"],["5日"],["7日"],["9日"]]
やったこと
sort()は引数に比較関数を指定することができるため、比較関数とparseInt()
を組みこむことで解決。
配列のそれぞれの要素の先頭を元に並び替えるので、parseInt()
を使って数値に変更。これで2桁以上の数値も取得できる。
1番目の要素から順番に要素の中身を比較関数で比較していく。
function compare(a,b){
let index = 0
let a_num = parseInt(a)
let b_num = parseInt(b)
if (a_num > b_num) {
index = 1
}else if (a_num < b_num) {
index = -1
}
return index
}
const odd_days = [
['1日'],['3日'],['13日'],['5日'],['9日'],['11日'],['7日'],['15日'],['17日'],
]
odd_days.sort(compare)
// odd_daysの中身が日付の昇順にソートされる
// [["1日"],["3日"],["5日"],["7日"],["9日"],["11日"],["13日"],["15日"],["17日"]]
公式ドキュメントにも詳しく書かれてあるが、比較関数(今回はcompore(a,b)
)の返り値が
0未満の場合、aがbより先に並ぶ=a,bの順に並ぶ
0の場合、aとbはそのまま=a,bの順に並ぶ
0以上の場合、bがaより先に並ぶ=b,aの順に並ぶ(順序が入れ替わる)
今回定義した比較関数compore(a,b)
では、まず配列の要素をそれぞれparseInt()
で数値に変換。その変換した数値a_num
とb_num
の大小を比較し、a_num
の方が大きい時だけ配列の要素を入れ替えている。parseInt()
で変換しているので2桁以上の数値も含めて昇順にソートできる。
実装満たせたのでリファクタしてみる
ちなみにcompare(a,b)
の中身は以下のようにリファクタリングできる。比較関数の返り値のしくみが分かればこのコードも理解できるはず。
function compare(a,b){
return parseInt(a) - parseInt(b)
}
さらにアロー関数を使うと関数定義もいらない。
odd_days.sort((a,b) => parseInt(a) - parseInt(b))
所感
いざ実装してみると実にシンプル。
調べても中々出てこなかったのでメモ。
参考
sort()
と比較関数
parseInt()
Discussion