Javascriptでソートを行う時、単純に各プロパティの順序でソートするのではなく、指定した順序でソートしたい場合がある。この場合はソートしたい順序を別途配列で定義し、その配列でのindexOfを使用し配列内のindexからソート順序を決定すると実現できる。
下記の例では、
- employees オブジェクトの配列をnameプロパティでソートしたいかつ、
- ソート順序を独自に指定したい場合
を示す。ソート順序を指定した配列を用意し、indexOfを使用してソートする。
// ソートする配列
let employees = [
{ name: "John", dob: "Dec 15, 2007", score: 80 },
{ name: "Ana", dob: "Jan 15, 2009", score: 75 },
{ name: "Alice", dob: "Ja 15, 2009", score: 75 },
{ name: "Bob", dob: "Jan 15, 2009", score: 90 },
{ name: "Cat", dob: "Jan 15, 2009", score: 75 },
{ name: "John", dob: "Jan 15, 2009", score: 80 },
{ name: "Zion", dob: "Feb 15, 2011", score: 90 },
];
// ソートしたい項目の順序を配列で持つ
const sortOrder = ["Bob", "Zion", "Ana", "John", "Cat", "Alice"];
employees.sort((a, b) => {
return sortOrder.indexOf(a.name) - sortOrder.indexOf(b.name);
});
// 結果
employees.forEach((e) => {
console.log(`${e.name} ${e.score}`);
});
// name文字列の大小の順序ではなく指定した順序でソートされる。
// Bob 90
// Zion 90
// Ana 75
// John 80
// John 80
// Cat 75
// Alice 75
解説
- 配列のsort関数
aとbの大小によって2つの要素の比較を繰り返すことによって昇順ソートする。文字列の場合、時刻の場合、オブジェクトの場合などはそれぞれ比較すればよく、基本的には同じである。
Array.sort((a, b) => {
return a - b;
});
// a>b 正
// a<b 負
// a=b 0
- indexOf配列はその配列内のindexを返す
const sortOrder = ["Bob", "Zion", "Ana", "John", "Cat", "Alice"];
console.log(sortOrder.indexOf("Zion")); // 1
console.log(sortOrder.indexOf("Ana")); // 2
console.log(sortOrder.indexOf("Alice")); // 5
- index同士を比較して、大小を決定する。
indexOfを利用することで、要素の比較ではなく、indexの比較を行う。
employees.sort((a, b) => {
return sortOrder.indexOf(a.name) - sortOrder.indexOf(b.name);
});
- 順序用の配列に存在しない場合は-1を返す
そのため、存在しない値はindexが最小となるため、必ず前方に配置される。