JavaScriptのsort()を使ってNaNを配列の末尾に移動する方法
はじめに
文字列と数値が混在する配列を扱う際、「NaN(Not a Number)の値は常に配列の末尾に配置されるようにソートしたい」という要件が生じることがあります。
この記事では、JavaScriptのsort()メソッドと比較関数(コンパレータ)を組み合わせて、次の順序で要素を並べ替える方法を解説します。
- 有効な数値(先頭)
- 文字列リテラル(中間)
- NaN(末尾)
実装コード
以下がそのコード例です。
const arr = [344, 'gfd', NaN, '', 15, 'f', 176, NaN, 736, NaN, 872, 859,
'string', 13, 'new', NaN, 75];
const sorter = (a, b) => {
if(a !== a){
return 1;
} else if(b !== b){
return -1;
}
return typeof a === 'number' ? -1 : 1;
};
arr.sort(sorter);
console.log(arr);
コードの解説
この比較関数の鍵となるのは、NaNの特殊な性質を利用した判定方法です。JavaScriptでは、NaNは自分自身と等しくない(NaN !== NaN が true になる)というユニークな特性を持っています。そのため、「a !== a」が true であれば、aはNaNであると確定できます。
比較関数sorterの戻り値の意味は以下の通りです。
- aがNaNの場合:1を返すことで、aをbの後ろ(末尾側)に移動させます。
- bがNaNの場合:-1を返すことで、bをaの後ろ(末尾側)に移動させます。
- どちらもNaNでない場合:aが数値型なら-1を返して先頭側へ、文字列型なら1を返して後ろ側へ配置します。
実行結果
コンソールには次のように出力されます。
[
75, 13, 859,
872, 736, 176,
15, 344, 'gfd',
'', 'f', 'string',
'new', NaN, NaN,
NaN, NaN
]
ご覧のとおり、数値が先頭に、文字列が中間に、NaNが4つすべて末尾に配置されています。なお、この比較関数は「型による並び順」を優先するため、数値同士の大小順序は保証されません。数値も昇順にソートしたい場合は、比較関数を次のように拡張します。
const sorter = (a, b) => {
if(a !== a) return 1; // aがNaN → 末尾へ
if(b !== b) return -1; // bがNaN → 末尾へ
if(typeof a === 'number' && typeof b === 'number'){
return a - b; // 数値同士は昇順で比較
}
return typeof a === 'number' ? -1 : 1;
};
まとめ
NaNは等価比較において自分自身と一致しないという性質を持つため、sort()の比較関数内で簡単に検出できます。このテクニックを使えば、混在データの配列からNaNだけを確実に末尾へ移動させ、整理された読みやすい配列を得ることができます。
-
JavaScriptのArray.prototype.sort()メソッドの使い方をサンプルコードで解説
Array.prototype.sort()は、JavaScriptで配列の要素を並べ替えるための組み込みメソッドです。アルファベット順・数値順といった並び方に加えて、昇順・降順も自由に指定でき、配列操作の中でも特に使用頻度の高いメソッドの一つです。 ただし重要なポイントとして、sort()メソッドはデフォルトではすべての要素を文字列に変換してから比較します。そのため、数値の配列を意図したとおりに並べ替えたい場合は、比較関数を引数として渡す必要があります。 以下は、Array.prototype.sort()メソッドの基本的な使い方を示すサンプルコードです。 サンプルコード <!DOC
-
JavaScriptのオブジェクト配列に配列メソッドを適用する方法
JavaScriptでは、オブジェクトが格納された配列に対しても、通常の配列と同じようにpop()、push()、splice()などの標準的な配列メソッドをそのまま使用できます。オブジェクト配列はあくまで「配列」であるため、要素としてオブジェクトが入っていても配列操作のAPIは共通で動作します。 コード例 以下は、JavaScriptオブジェクトの配列に対して配列メソッドを使用するサンプルコードです。 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8