JavaScriptのArrayクラスには、配列を変換するための強力な組み込みメソッドがたくさんあります。これらのメソッドを使えば、単純なforループやより直接的な操作で変換するよりも、はるかに簡単にある配列を別の配列へ変換できます。
一部のメソッドは純粋で、元の配列を変更しません。代わりに新しい配列を返します。一方、別のメソッドは呼び出された配列自体を操作し、変更後の配列を返しません。
配列を変換するためによく使われるメソッドの一部を以下に紹介します。利用できるメソッドの完全なリストは、MDNのドキュメントにあります。
引数として渡された関数に従って各要素を変換し、新しい配列を作ります。これらのコールバック関数は、しばしばアロー関数として書かれます。
let arr = [1, 2, 3, 4];
const newArr = arr.map((value) => value - 1);
console.log(newArr);
// => [0, 1, 2, 3]
console.log(arr);
// => [1, 2, 3, 4]
なお、できあがる配列の長さは、元の配列と必ず同じになります。
絞り込み用の関数(要素を残すならtrue、取り除くならfalseを返すもの)を与えると、現在の配列を絞り込んで新しい配列を作ります。
let arr = [1, 2, 3, 4];
arr.filter((value) => value % 2 === 0);
// => [2, 4]
_アキュムレーター_と配列の現在の要素を仮引数として受け取る関数を使って、配列を1つの値にまとめます。この関数は、現在の要素をどのようにアキュムレーターへ統合するかを指示し、次の繰り返しで使われるアキュムレーターを返します。
let arr = [1, 2, 3, 4];
// Get the sum of elements
arr.reduce((accumulator, currentValue) => accumulator + currentValue, 0);
// => 10
// Classify the numbers by whether they are odd or not
arr.reduce(
(accumulator, currentValue) => {
if (currentValue % 2 === 0) {
accumulator.even.push(currentValue);
} else {
accumulator.odd.push(currentValue);
}
return accumulator;
},
{ even: [], odd: [] },
);
// => { even: [2, 4], odd: [1, 3] }
配列の要素を逆順にします。
const arr = [1, 2, 3, 4];
arr.reverse();
// => [4, 3, 2, 1]
このメソッドは、呼び出された配列自体を変更します。
開始インデックスと終了インデックスを指定すると、呼び出された配列から部分配列を作ります。
終了インデックスの位置にある要素は含まれません。また、すべての仮引数は省略可能です。開始インデックスの既定値は0で、終了インデックスの既定値は配列の長さです。
const arr = [1, 2, 3, 4];
arr.slice(1, 2); // [2]
arr.slice(1); // [2, 3, 4]
// You can also use negative numbers, that represent the indexes
// starting from the end of the array
arr.slice(-2); // [3, 4]
配列の要素を削除したり、置き換えたり、新しい要素を追加したりします。次の仮引数を受け取ります。
spliceは、削除された要素を返します。
const arr = ['1', '2', '5', '6'];
// Insert an element at index 2
arr.splice(2, 0, '3');
console.log(arr);
// => ['1', '2', '3', '5', '6']
// Remove 2 elements, starting at index 3 and insert 2 elements
const removed = arr.splice(3, 2, '4', '5');
console.log(removed);
// => ['5', '6']
console.log(arr);
// => ['1', '2', '3', '4', '5']
// Remove 1 element at index 1
arr.splice(1, 1);
console.log(arr);
// => ['1', '3', '4', '5']
既定では、sortはまず要素を文字列に変換し、次に文字列の比較を行って、配列の要素を並べ替えます(比較の概念を参照)。並べ替えは_その場で_行われ、つまり元の配列が変更されます。sortは変更後の配列も返すので、他のメソッドをつなげたいときに便利です。
const arr = ['c', 'a', 'z', 'b'];
const result = arr.sort();
console.log(result);
// => ['a', 'b', 'c', 'z']
console.log(arr);
// => ['a', 'b', 'c', 'z']
この既定の動作は、数値を並べ替えようとすると間違った結果になります。
const arr = [3, 1, 2, 10];
arr.sort();
// => [1, 10, 2, 3]
// Because the string '10' comes before '2' in dictionary order.
並べ替えの動作をカスタマイズするには、比較関数を引数として渡します。比較関数は、配列の2つの要素を引数として呼び出されます。そして、次のいずれかを返す必要があります。
0
これで、正しい比較関数を渡せば、数値の並べ替えの問題を解決できます。
const arr = [3, 1, 2, 10];
arr.sort((a, b) => a - b);
// => [1, 2, 3, 10]
// "a - b" is negative when b is greater than a, positive when
// a is greater than b and 0 when they are equal.
次に、カスタムの比較関数を使ってオブジェクトの配列を並べ替える例を示します。
const arr = [
{ name: 'Lydia', age: 7 },
{ name: 'Anne', age: 34 },
{ name: 'Holger', age: 59 },
];
arr.sort((item1, item2) => {
if (item1.name < item2.name) {
return -1;
}
if (item1.name > item2.name) {
return 1;
}
return 0;
});
// => [ { name: 'Anne', age: 34 }, { name: 'Holger', age: 59 },
// { name: 'Lydia', age: 7 } ]
2019年以降、言語仕様では並べ替えが安定でなければならないと定められていますが、性能(時間計算量と空間計算量)については保証がありません。