HOWTO · JavaScript

JavaScript でオブジェクトの配列をプロパティで並べ替える

このチュートリアルでは、オブジェクトの配列をいくつかのプロパティで並べ替える方法を示します。

このページの内容

オブジェクトの配列をプロパティで並べ替えるには、sort() に比較関数を渡します。比較関数は2つのオブジェクトからそのプロパティを読み取り、最初のオブジェクトを前に置く場合は負の数、後ろに置く場合は正の数、キーが等しい場合は0を返します。文字列キーには文字列比較を、数値キーには減算を使います。

文字列プロパティでオブジェクトの配列を並べ替える

比較する前に2つの文字列を正規化すると、大文字と小文字を区別せずに並べ替えられます。この例では、各オブジェクトの元の lastName の値を保ったまま比較できます。

次の例を実行します。

このセクションのコードと表示されるラベルや出力は英語のままです。

const students = [
  { firstName: 'Rohan', lastName: 'Dalal', age: 19 },
  { firstName: 'Zain', lastName: 'Ahmed', age: 17 },
  { firstName: 'Anadi', lastName: 'Malhotra', age: 19 }
];

students.sort((a, b) => {
  const left = a.lastName.toLowerCase();
  const right = b.lastName.toLowerCase();
  if (left < right) return -1;
  if (left > right) return 1;
  return 0;
});

console.log(students.map(student => student.lastName).join(', '));
Ahmed, Dalal, Malhotra

比較関数が返すのは、sort() が必要とする並べ替えの指標です。戻り値は厳密に -1 または 1 である必要はなく、負の値、0、正の値のいずれかであればかまいません。大文字と小文字を順序に影響させたくない場合は、小文字に変換して比較すると便利です。toLowerCase() は新しい文字列を返すため、オブジェクトに保存された名前は変わりません。

localeCompare()で文字列を並べ替える

文字列プロパティには、簡潔な比較関数として localeCompare() を使えます。言語ごとの並べ替え規則も考慮されます。負の数、0、正の数を返すため、そのまま sort() に渡せます。

このセクションのコードと表示されるラベルや出力は英語のままです。

const students = [
  { firstName: 'Rohan', lastName: 'Dalal', age: 19 },
  { firstName: 'Zain', lastName: 'Ahmed', age: 21 },
  { firstName: 'Anadi', lastName: 'Malhotra', age: 16 }
];

students.sort((a, b) => a.lastName.localeCompare(b.lastName));
console.log(students.map(student => student.lastName).join(', '));
Ahmed, Dalal, Malhotra

キーがテキストで、言語に応じた比較が適切な場合は、この方法を使います。localeCompare() が比較するのは文字列であり、数値の並べ替えには使えません。言語を明示したい場合や、大文字と小文字の扱いなどのオプションを指定したい場合は、実行環境がサポートするロケールとオプションを localeCompare() に渡します。

数値プロパティで並べ替える

2つ目のオブジェクトの数値キーを、1つ目のオブジェクトの数値キーから引きます。最初の年齢が小さい場合、a.age - b.age は負の値になります。そのため、昇順では a が b より前に置かれます。

このセクションのコードと表示されるラベルや出力は英語のままです。

const students = [
  { firstName: 'Rohan', lastName: 'Dalal', age: 19 },
  { firstName: 'Zain', lastName: 'Ahmed', age: 21 },
  { firstName: 'Anadi', lastName: 'Malhotra', age: 16 }
];

students.sort((a, b) => a.age - b.age);
console.log(students.map(student => student.age).join(', '));
16, 19, 21

この減算の方法は数値に使います。名前には使わないでください。文字列を引いても、アルファベット順を表す比較にはなりません。同様に、比較関数を省略しても sort() がオブジェクトのプロパティを調べるわけではありません。既定の並べ替えでは配列要素を文字列に変換して比較するため、オブジェクトを並べ替えるには通常、明示的な比較関数が必要です。

降順に並べ替える

比較関数に渡すオペランドの順序を逆にすると、並べ替えの方向も逆になります。年齢を数値で比較する場合、b.age - a.age とすれば年齢の高い人が先になります。こうすると、選択したプロパティに比較ルールを結び付けたままにでき、昇順に並べ替えた配列を後から逆順にする必要もありません。

このセクションのコードと表示されるラベルや出力は英語のままです。

const students = [
  { firstName: 'Rohan', lastName: 'Dalal', age: 19 },
  { firstName: 'Zain', lastName: 'Ahmed', age: 21 },
  { firstName: 'Anadi', lastName: 'Malhotra', age: 16 }
];

students.sort((a, b) => b.age - a.age);
console.log(students.map(student => student.age).join(', '));
21, 19, 16

文字列を降順にするには、文字列比較の結果を反転します。たとえば、a.lastName.localeCompare(b.lastName) の符号を反転できます。比較関数の動作に一貫性を持たせ、キーが等しい場合は0を返すようにしてください。

sort()の動作と注意点

sort() は配列をその場で変更し、変更後の同じ配列を返します。元の順序も残しておきたい場合は、先に const sortedStudents = [...students] で配列をコピーし、そのコピーを並べ替えます。オブジェクト自体は複製されないため、変わるのは配列内の位置であり、オブジェクトのプロパティではありません。

比較関数を指定しない場合、sort() は値を文字列に変換して比較します。そのため、既定の並べ替えは数値順にしたい場合や、オブジェクトの特定のプロパティを基準にしたい場合には適しません。キーの型に合った比較関数を指定してください。ここでの例は、各オブジェクトに指定した文字列または数値のプロパティがあることを前提としています。キーがない場合や型が混在する場合の扱いは定めていないため、比較関数を適用する前にデータを検証するか、それらの値をどう比較するかを決めてください。

配列APIの詳細については、[sort() メソッドのリファレンス]を参照してください。