JavaScriptでnull値を持つプロパティを含む配列オブジェクトを並べ替える方法
JavaScriptでは、複数のオブジェクトを格納した配列を扱う際、一部のプロパティ(キー)に null が設定されているケースによく出会います。この記事では、そのような null 値を含む配列を適切にソートする方法を解説します。
要件の整理
今回作成するJavaScriptの関数は、以下の条件を満たす必要があります。
・オブジェクトの配列を受け取る
・オブジェクトの中には、値として null が割り当てられているキーが存在する場合がある
・null を持つオブジェクトはすべて配列の末尾に移動する
実装のポイント
この問題を解く鍵は、null を比較可能な数値に置き換えてからソートすることです。ここでは null を Infinity に変換することで、どのような数値よりも大きい値として扱い、自然に配列の末尾へ配置できるようにしています。
実際のコードは次のとおりです。
const arr = [
{key: 'a', value: 100},
{key: 'a', value: null},
{key: 'a', value: 0}
];
const sortNullishValues = (arr = []) => {
// nullの場合はInfinityに置き換え、それ以外は元の値を返す
const assignValue = val => {
if(val === null){
return Infinity;
}
else{
return val;
};
};
// 置き換えた値同士を比較してソートする
const sorter = (a, b) => {
return assignValue(a.value) - assignValue(b.value);
};
arr.sort(sorter);
}
sortNullishValues(arr);
console.log(arr);実行結果
このコードをコンソールで実行すると、以下の出力が得られます。
[
{ key: 'a', value: 0 },
{ key: 'a', value: 100 },
{ key: 'a', value: null }
]コードの解説
処理の流れを簡単にまとめると、次のようになります。
1. assignValue関数: 引数として受け取った値が null かどうかを判定し、null であれば Infinity を、そうでなければ元の値を返します。
2. sorter関数: 2つのオブジェクトを受け取り、それぞれの value プロパティに assignValue を適用した上で減算します。Array.prototype.sort() の比較関数として機能します。
3. ソートの実行: 減算の結果、通常の数値は昇順に並び替えられ、Infinity に変換された null の要素は必ず最大値として扱われるため、自動的に配列の末尾に配置されます。
補足:より簡潔な書き方
アロー関数と三項演算子を使えば、このロジックはさらに簡潔に記述できます。
const sortNullishValues = (arr = []) => {
arr.sort((a, b) =>
(a.value === null ? Infinity : a.value) -
(b.value === null ? Infinity : b.value)
);
};なお、文字列など数値以外の値が混在する場合は、減算による比較が意図しない結果(NaN)を生む可能性があるため注意が必要です。そのようなケースでは、型チェックを追加して対応すると安全です。
-
JavaScriptのlengthプロパティで配列オブジェクトの長さを取得する方法
JavaScriptにおけるlengthプロパティとはJavaScriptのlengthプロパティは、文字列や配列などのオブジェクトが持つ要素数(サイズ)を返すために使用されます。配列の場合は格納されている要素の個数、文字列の場合は文字数を取得できます。ここでは、文字列と配列オブジェクトの長さをlengthプロパティで取得するサンプルコードを紹介します。サンプルコード以下の例では、ボタンをクリックすると配列の長さが画面に表示される仕組みを実装しています。<!DOCTYPE html> <html lang="ja"> <head> <
-
JavaScriptで2つのオブジェクトを比較しながら配列のネストされた値をグループ化する方法
この記事では、2つのオブジェクト(before と after)を比較しながら、ネストされた配列の値を1つの行にグループ化する方法を解説します。データの差分を表形式で整理したい場合などに役立つテクニックです。入力データの例まず、次のようなJSONオブジェクトがあるとします。before(変更前)と after(変更後)の2つの状態が含まれ、それぞれの device 配列の中に、id、price、features(機能名と価格)というネストされた構造を持っています。const input = { before: { device: [ { id: 1234