以前に配列の使い方についてまとめた記事を投稿しましたが、それ以降も配列関連の記事を投稿したり学んだりしているので、あらためて配列まわりの記述についてまとめてみます。
生成・取得
基本的な配列の生成・取得は以下のように行います。
// 配列の生成 const array = []; console.log(array); // [] // データを格納した状態で配列を生成 const array2 = ['data1', 'data2', 'data3']; console.log(array2); // ['data1', 'data2', 'data3'] // 配列内の値取得 console.log(array2[1]); // data2
Array()を使った生成は以下のようになります。
// Array()を使った配列の生成
const array3 = Array();
console.log(array3); // []
// 引数が単一の場合、その値がlengthに設定され、値は空の配列を生成
const array5 = Array(3);
console.log(array5); // [empty × 3]
console.log(array5.length); // 3
console.log(array5[1]); // undefined
// 引数が複数の場合、その値で配列を生成
const array4 = Array('data1', 'data2', 'data3');
console.log(array4); // ['data1', 'data2', 'data3']
配列の値はat()を使うことでも取得できます。
配列の最後の値を取得する際、[]の場合はlengthを使用しますが、at()の場合は引数に-1を指定することで取得できます。
// 配列の値を取得 const array = ['A', 'B', 'C', 'D', 'E']; console.log(array.at(1)); // B console.log(array.at(-1)); // E
配列の範囲を指定して取得
配列内の開始位置と終了位置を指定して値を取得する場合、slice()を使用します。
// 配列の範囲を指定して取得 const array = ['A', 'B', 'C', 'D', 'E']; // 2番目〜4番目まで取得 console.log(array.slice(1, 4)); // ['B', 'C', 'D'] // 3番目〜最後まで取得 console.log(array.slice(2)); // ['C', 'D', 'E']
配列の長さ取得
配列内の要素数を取得する場合はlengthを使用します。
// 配列の長さ取得 const array = ['data1', 'data2', 'data3']; console.log(array.length); // 3
引数から配列を生成
of()は受け取った引数から配列を生成します。
// 引数から配列を生成 const array = Array.of(1, 2, 3); console.log(array); // [1, 2, 3]
文字列から配列を生成
split()は文字列を指定した値で区切って、配列を生成します。
// 文字列から配列を生成
const url = 'https://cly7796.net/blog/';
console.log(url.split('/')); // ['https:', '', 'cly7796.net', 'blog', '']
配列から文字列を生成
split()とは逆に、join()は配列を指定した値で結合して、文字列を生成します。
// 配列から文字列を生成
const url = ['https://cly7796.net', 'blog', 'category', 'javascript'];
console.log(url.join('/')); // https://cly7796.net/blog/category/javascript
toString()もjoin()と同様に配列から文字列を生成しますが、結合する文字列の指定はできず、「,」での区切りになります。
// 配列から文字列を生成 const url = ['A', 'B', 'C', 'D']; console.log(url.toString()); // A,B,C,D
ArrayオブジェクトはObjectのtoString()をオーバーライドしていて、また配列のtoString()は内部的にjoin()を呼び出しているようです。
配列から文字列を生成するデモページ
配列同士を結合して配列を生成
concat()は配列同士を結合して、新しい配列を生成します。
// 配列同士を結合して配列を生成 const array = ['data1', 'data2', 'data3']; const array2 = ['dataA', 'dataB', 'dataC']; console.log(array.concat(array2)); // ['data1', 'data2', 'data3', 'dataA', 'dataB', 'dataC']
配列風オブジェクトから配列を生成
from()は配列風オブジェクトや反復可能オブジェクトから配列を生成します。
<a href="https://www.google.com/">Google</a> <a href="https://www.yahoo.co.jp/">Yahoo</a> <a href="https://www.amazon.co.jp/">Amazon</a>
// 文字列から配列を生成
const array = Array.from('abcde');
console.log(array); // ['a', 'b', 'c', 'd', 'e']
// Setから配列を生成
const set = new Set(['foo', 'bar', 'baz', 'foo']);
console.log(set); // {'foo', 'bar', 'baz'}
const array2 = Array.from(set);
console.log(array2); // ['foo', 'bar', 'baz']
// Mapから配列を生成
const map = new Map([[1, 2], [2, 4], [4, 8]]);
console.log(map);
const array3 = Array.from(map);
console.log(array3); // [[1, 2], [2, 4], [4, 8]]
// NodeListから配列を生成
const links = document.getElementsByTagName('a');
const url = Array.from(links, function(a) {
return a.href;
});
console.log(url); // ['https://www.google.com/', 'https://www.yahoo.co.jp/', 'https://www.amazon.co.jp/']
配列からイテレータを生成
entries()は配列内のキーと値のペアで新しいイテレータを生成します。
// 配列の各要素のkey/valueのペア
const array = ['A', 'B', 'C'];
for(const element of array.entries()) {
console.log(element);
}
// [0, 'A']
// [1, 'B']
// [2, 'C']
for(const [index, element] of array.entries()) {
console.log(index, element);
}
// 0 'A'
// 1 'B'
// 2 'C'
keys()は配列内のキーで新しいイテレータを生成します。
// 配列の各要素のkey/valueのペア
const array = ['A', 'B', 'C'];
for(const element of array.keys()) {
console.log(element);
}
// 0
// 1
// 2
values()は配列内の値で新しいイテレータを生成します。
// 配列の各要素のkey/valueのペア
const array = ['A', 'B', 'C'];
for(const element of array.values()) {
console.log(element);
}
// A
// B
// C
配列要素の追加・削除
配列の先頭に追加
// 配列の先頭に追加
const array = ['data1', 'data2', 'data3'];
array.unshift('data0');
console.log(array); // ['data0', 'data1', 'data2', 'data3']
配列の末尾に追加
// 配列の末尾に追加
const array = ['data1', 'data2', 'data3'];
array.push('data4');
console.log(array); // ['data1', 'data2', 'data3', 'data4']
配列の先頭を削除
// 配列の先頭を削除 const array = ['data1', 'data2', 'data3']; array.shift(); console.log(array); // ['data2', 'data3']
配列の末尾を削除
// 配列の末尾を削除 const array = ['data1', 'data2', 'data3']; array.pop(); console.log(array); // ['data1', 'data2']
配列の指定位置への操作
配列の指定位置に値を追加・指定位置の値を削除
// 配列の指定位置への操作 const array = ['data1', 'data2', 'data3', 'data4', 'data5']; // 配列の2番目から2つ削除 array.splice(1, 2); console.log(array); // ['data1', 'data4', 'data5'] // 配列の2番目に値を2つ追加 array.splice(1, 0, 'data6', 'data7'); console.log(array); // ['data1', 'data6', 'data7', 'data4', 'data5']
配列の値の変更
fill()は配列内の指定した範囲を指定した値で変更します。
// 配列の2番目から4番目までをfillに変更
const array = ['data1', 'data2', 'data3', 'data4', 'data5'];
array.fill('fill', 1, 4);
console.log(array); // ['data1', 'fill', 'fill', 'fill', 'data5']
// 配列の2番目から最後までをfillに変更
const array2 = ['data1', 'data2', 'data3', 'data4', 'data5'];
array2.fill('fill', 1);
console.log(array2); // ['data1', 'fill', 'fill', 'fill', 'data5']
// 配列の値全てをfillに変更
const array3 = ['data1', 'data2', 'data3', 'data4', 'data5'];
array3.fill('fill');
console.log(array3); // ['data1', 'fill', 'fill', 'fill', 'data5']
多次元配列の操作
flat()は多次元配列のネストをフラットにした新しい配列を返します。
// 多次元配列のネストをフラットにする const array = [1, 2, 3, 4, 5, [5, 6]]; const flat = array.flat(); console.log(flat); // [1, 2, 3, 4, 5, 5, 6] // 新しく配列を生成するので、元の配列はそのまま console.log(array); // [1, 2, 3, 4, 5, [5, 6]]; // 空配列の場合は除外される const array2 = [1, 2, [], 3, 4, 5, [5, 6]]; const flat2 = array2.flat(); console.log(flat2); // [1, 2, 3, 4, 5, 5, 6] const array3 = [1, 2, 3, 4, 5, [5, [6, 7, 8]]]; const flat3 = array3.flat(); console.log(flat3); // [1, 2, 3, 4, 5, 5, [6, 7, 8]] const flat4 = array3.flat(2); console.log(flat4); // [1, 2, 3, 4, 5, 5, 6, 7, 8]
判別・検索
配列かどうかを判別
isArray()は配列かどうかを判別して真偽値を返します。
// 配列かどうかを判別 const array = ''; console.log(Array.isArray(array)); // false // 配列かどうかを判別 const array2 = []; console.log(Array.isArray(array2)); // true
配列内に値があるかを調べる
includes()は指定した値が配列内にあるかどうかを真偽値で返します。
// 配列内に値があるかを調べる
const array = ['data1', 'data2', 'data3'];
console.log(array.includes('data2')); // true
console.log(array.includes('data4')); // false
indexOf()は配列内で指定した値と一致する最初のインデックス番号を返します。
配列内にない値の場合は-1を返します。
// 配列かどうかを判別
const array = ['data1', 'data2', 'data3'];
console.log(array.indexOf('data2')); // 1
console.log(array.indexOf('data4')); // -1
lastIndexOf()は配列内で指定した値と一致する最後のインデックス番号を返します。
配列内にない値の場合は-1を返します。
// 配列内に値があるかを調べる
const array = ['data1', 'data2', 'data3'];
console.log(array.lastIndexOf('data2')); // 1
console.log(array.lastIndexOf('data4')); // -1
配列内に条件を満たす値があるかを調べる
some()は指定した条件を満たす値が配列内にあるかどうかを真偽値で返します。
// 配列内に条件を満たす値があるかを調べる
const array = [5, 12, 8, 130, 44];
const result1 = array.some(function(element) {
return element > 10;
});
console.log(result1); // true
const result2 = array.some(function(element) {
return element > 1000;
});
console.log(result2); // false
every()は指定した条件を配列内の全ての値が満たすかどうかを真偽値で返します。
// 配列内の全ての値が条件を満たすかを調べる
const array = [5, 12, 8, 130, 44];
const result1 = array.every(function(element) {
return element > 10;
});
console.log(result1); // false
const result2 = array.every(function(element) {
return element < 1000;
});
console.log(result2); // true
findIndex()は配列内で指定した条件を満たす最初のインデックス番号を返します。
条件を満たす値が見つからなかった場合は-1を返します。
// 配列内に条件を満たす値があるかを調べる
const array = [5, 12, 8, 130, 44];
const result1 = array.findIndex(function(element) {
return element > 10;
});
console.log(result1); // 1
const result2 = array.findIndex(function(element) {
return element > 1000;
});
console.log(result2); // -1
findLastIndex()は配列内で指定した条件を満たす最後のインデックス番号を返します。
条件を満たす値が見つからなかった場合は-1を返します。
// 配列内に条件を満たす値があるかを調べる
const array = [5, 12, 8, 130, 44];
const result1 = array.findLastIndex(function(element) {
return element > 10;
});
console.log(result1); // 4
const result2 = array.findLastIndex(function(element) {
return element > 1000;
});
console.log(result2); // -1
find()は配列内で指定した条件を満たす最初の値を返します。
条件を満たす値が見つからなかった場合はundefinedを返します。
// 配列内に条件を満たす値があるかを調べる
const array = [5, 12, 8, 130, 44];
const result1 = array.find(function(element) {
return element > 10;
});
console.log(result1); // 12
const result2 = array.find(function(element) {
return element > 1000;
});
console.log(result2); // undefined
findLast()は配列内で指定した条件を満たす最後の値を返します。
条件を満たす値が見つからなかった場合はundefinedを返します。
// 配列内に条件を満たす値があるかを調べる
const array = [5, 12, 8, 130, 44];
const result1 = array.findLast(function(element) {
return element > 10;
});
console.log(result1); // 44
const result2 = array.findLast(function(element) {
return element > 1000;
});
console.log(result2); // undefined
並び順の変更
reverse()は配列内の要素を逆順にします。
// 配列を逆順にする const array = ['A', 'B', 'C', 'D', 'E']; const reverse = array.reverse(); console.log(reverse); // ['E', 'D', 'C', 'B', 'A'] // 新しく配列を作るわけではないので、元の配列も逆順になる console.log(array); // ['E', 'D', 'C', 'B', 'A']
toReversed()はreverse()と同じく配列内の要素を逆順にしますが、新しく配列を作成するので元の配列は変更されません。
// 新しい配列で逆順にする const array = ['A', 'B', 'C', 'D', 'E']; const reverse = array.toReversed(); console.log(reverse); // ['E', 'D', 'C', 'B', 'A'] // 新しく配列を作るので、元の配列は変更されない console.log(array); // ['A', 'B', 'C', 'D', 'E']
sort()は配列内で要素内の要素を指定した形で並び替えます。
// 配列の要素を並び替え(昇順)
const array = ['A', 'C', 'E', 'D', 'B', 1, 30, 4, 21, 100000];
const sort = array.sort();
console.log(sort); // [1, 100000, 21, 30, 4, 'A', 'B', 'C', 'D', 'E']
// 新しく配列を作るわけではないので、元の配列も逆順になる
console.log(array); // [1, 100000, 21, 30, 4, 'A', 'B', 'C', 'D', 'E']
// 配列の要素を並び替え
const array2 = [1, 30, 4, 21, 100000];
array2.sort(function(a, b) {
if (a < b) {
return -1;
}
if (b > a) {
return 1;
}
return 0;
});
console.log(array2); // [1, 4, 21, 30, 100000]
配列を指定した形で並び替えるデモページ
sort()について詳しくは過去に書いた記事をご確認ください。
toSorted()はsort()と同じく配列内の要素を並び替えますが、新しく配列を作成するので元の配列は変更されません。
// 新しい配列で要素を並び替え(昇順) const array = ['A', 'C', 'E', 'D', 'B', 1, 30, 4, 21, 100000]; const sort = array.toSorted(); console.log(sort); // [1, 100000, 21, 30, 4, 'A', 'B', 'C', 'D', 'E'] // 新しく配列を作るので、元の配列は変更されない console.log(array); // ['A', 'C', 'E', 'D', 'B', 1, 30, 4, 21, 100000]
配列のループ
配列内の各要素に対してコールバックで処理を行うメソッドを見てみます。
forEach()は配列内の各要素に対して処理を行います。
// 配列のループ処理
const array = ['A', 'B', 'C'];
array.forEach(function(element, index) {
console.log(element, index);
});
// A 0
// B 1
// C 2
配列の絞り込み
filter()は指定した条件に合う値のみを抽出して、新しい配列を返します。
// 配列の絞り込み
const array = [1, 2, 3, 4, 5];
const filter = array.filter(function(element) {
return element > 3
});
console.log(filter); // [4, 5]
// 新しく配列を生成するので、元の配列はそのまま
console.log(array); // [1, 2, 3, 4, 5]
配列の加工
map()は配列の各要素に指定した処理を行い、その結果を元に新しい配列を返します。
// 配列の加工
const array = [1, 2, 3, 4, 5];
const map = array.map(function(element, index, array) {
return element * 2;
});
console.log(map); // [2, 4, 6, 8, 10]
// 新しく配列を生成するので、元の配列はそのまま
console.log(array); // [1, 2, 3, 4, 5]
flatMap()は配列に対してmap()を行った後にflat()を行い、新しい配列を返します。
const array = ["Sunny in", "", "California"];
// map()の場合
const map = array.map(function(element, index, array) {
return element.split(' ');
});
console.log(map); // [['Sunny', 'in'], [''], ['California']]
// flatMap()の場合
const flatMap = array.flatMap(function(element, index, array) {
return element.split(' ');
});
console.log(flatMap); // ['Sunny', 'in', '', 'California']
reduce()は配列の各要素に指定した処理を行い、最終的に1つの値を取得します。
各要素に対する処理の中で、現在の値やこれまでの値などを使うことができます。
// 配列の加工(配列の総和)
const array = [1, 2, 3, 4, 5];
const reduce = array.reduce(function(previousValue, currentValue, currentIndex, array) {
return previousValue + currentValue;
});
console.log(reduce); // 15
// 配列の加工(配列の各要素を2倍の値にした新しい配列の作成)
const reduce2 = array.reduce(function(previousValue, currentValue, currentIndex, array) {
previousValue.push(currentValue * 2);
return previousValue;
}, []);
console.log(reduce2); // [2, 4, 6, 8, 10]
// 新しく配列を生成するので、元の配列はそのまま
console.log(array); // [1, 2, 3, 4, 5]
配列の加工のデモページ2
reduce()について詳しくは過去に書いた記事をご確認ください。
reduceRight()はreduce()と基本的には同じですが、処理の順番が配列の先頭からではなく末尾からという点が異なります。
// 配列の加工(配列の各要素を2倍の値にした新しい配列の作成)
const array = [1, 2, 3, 4, 5];
const reduceRight = array.reduceRight(function(previousValue, currentValue, currentIndex, array) {
previousValue.push(currentValue * 2);
return previousValue;
}, []);
console.log(reduceRight); // [10, 8, 6, 4, 2]
// 新しく配列を生成するので、元の配列はそのまま
console.log(array); // [1, 2, 3, 4, 5]
その他
ここまで見てきたメソッドの使用例をいくつか試してみます。
同じ値で初期化した配列の生成
fill()を使って、同じ値で初期化した配列を生成できます。
// 初期値の入った配列の生成
const array = Array(10).fill(0);
console.log(array); // [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
// 初期値にオブジェクトを設定すると参照渡しになるため注意
const array2 = Array(3).fill({
'title': '',
'body': ''
});
array2[0].title = 'test';
console.log(array2); // [{title: 'test', body: ''}, {title: 'test', body: ''}, {title: 'test', body: ''}]
連番の配列の生成
from()を使って連番の配列を生成する関数を作成します。
// 連番の配列の生成
function generate_sequence_array(start, stop, step) {
return Array.from({ length: (stop - start) / step + 1}, (element, index) => start + (index * step));
}
console.log(generate_sequence_array(0, 4, 1)); // [0, 1, 2, 3, 4]
console.log(generate_sequence_array(1, 10, 2)); // [1, 3, 5, 7, 9]
const alphabet = generate_sequence_array('A'.charCodeAt(0), 'Z'.charCodeAt(0), 1).map(function(element) {
return String.fromCharCode(element);
});
console.log(alphabet); // ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
最後で試しているように、アルファベットの一覧みたいな生成も可能です。
連番の配列を生成するデモページ
既存の配列から新しい配列を生成
配列のシャローコピーもしくはディープコピーする方法はいくつかあります。
シャローコピーとディープコピーについて詳しくは以前投稿した記事をご確認ください。
まずはシャローコピーです。
const array = [1, 2, 3, 4, 5]; // スプレッド構文でコピー const copy1 = [...array]; copy1[0] = 'spread'; console.log(copy1); // ['spread', 2, 3, 4, 5] // from()でコピー const copy2 = Array.from(array); copy2[1] = 'from'; console.log(copy2); // [1, 'from', 3, 4, 5] // slice()でコピー const copy3 = array.slice(); copy3[2] = 'slice'; console.log(copy3); // [1, 2, 'slice', 4, 5] // concat()でコピー const copy4 = array.concat(); copy4[3] = 'concat'; console.log(copy4); // [1, 2, 3, 'concat', 5] console.log(array); // [1, 2, 3, 4, 5]
次にディープコピーです。
const array = [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]];
const copy1 = JSON.parse(JSON.stringify(array));
copy1[0][0] = 'deepcopy';
console.log(copy1); // [['deepcopy', 2, 3, 4, 5], [6, 7, 8, 9, 10]]
const copy2 = structuredClone(array);
copy2[0][1] = 'structuredClone';
console.log(copy2); // [[1, 'structuredClone', 3, 4, 5], [6, 7, 8, 9, 10]]
const copy3 = array.map(function(element) {
return [...element]
});
copy3[0][2] = 'map';
console.log(copy3); // [[1, 2, 'map', 4, 5], [6, 7, 8, 9, 10]]
console.log(array); // [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]]
以前投稿した記事にも記載しましたが、JSON.parse()・JSON.stringify()を使用する方法やstructuredClone()を使用する場合、配列内の値によってはうまくコピーできない場合があるのでご注意ください。
ディープコピーのデモページ
配列内で条件に一致しない値の除外
flatMap()を使って条件に一致しない値を除外することができます。
const array = [5, 4, -3, 20, 17, -33, -4, 18];
// 0未満の値の除外
const result = array.flatMap(function(currentValue) {
if (currentValue < 0) {
return [];
}
return currentValue;
});
console.log(result); // [5, 4, 20, 17, 18]
条件に一致しない場合に空配列を返すことで、最終的に空配列が除外されます。
条件に一致しない値を除外するデモページ
配列内の最大値・最小値を調べる
apply()を使って配列内の最大値・最小値を調べます。
const array = [1, 2, 3, 4, 5]; console.log(Math.min.apply(null, array)); // 1 console.log(Math.max.apply(null, array)); // 5
配列内の重複する値を削除する
Setとfrom()を使って、配列内の重複する値を削除します。
const array = [1, 2, 2, 3, 1, 'a', 'b', 'c', 2, 'b', 'a']; const array2 = Array.from(new Set(array)); console.log(array2); // [1, 2, 3, 'a', 'b', 'c']
Setオブジェクトは一意の値のみの格納(重複する値を格納できない)となっていて、そこからfrom()で新しい配列を生成しています。
配列内の最大値・最小値を調べるデモページ
2024/4/27追記
toReversed()とtoSorted()を追加しました。
コメントが承認されるまで時間がかかります。