プログラミングで文字列操作と同じくらいよく扱うのが、配列やリストの操作です。
複数のデータを管理する配列やリストには、様々な種類があり、用途に応じて使い分けることが重要となります。
本記事では、JavaScriptの配列・リストについて、種類と操作方法をまとめました。
プログラミング初心者の方の学習や、忘れてしまった方の復習として、参考にしていただければ幸いです。
記載しているプログラムは、Node.js12.18.4を使って動作確認をしています。
JavaScriptの配列・リスト操作
配列・リスト操作として、以下の内容をとりあげます。
- 配列・リストの種類
- 配列・リストの作成
- 配列・リストから値を取得する
- 配列・リストの長さ(要素数)を取得する
- 配列・リストに要素を追加する
- 配列・リストから要素を削除する
- 配列・リストをコピーする
- 配列・リストをループさせる
- 配列・リストの順番を入れ替える
- 配列・リスト同士を結合する
- 配列・リストを検索する
配列・リストの種類
複数のデータを管理する配列やリストは、プログラミング言語によって様々なデータ構造がサポートされています。
JavaScriptでは、以下の3種類を扱うことができます。
- 配列:Array型として定義する。1つの要素に1つのデータが入る。インデックスは番号で管理される。
- 連想配列:Object型として定義する。1つの要素にkeyとvalueからなるセットのデータが入る。インデックスはkeyの値で管理される。
- マップ:Map型として定義する。連想配列とデータ構造は同じだが、専用の関数が用意されているため便利。
今回は主に、配列に関する操作を中心にまとめていきます。
配列・リストの作成
配列の作成方法は、初期値を指定しない作成、初期値を指定する作成、ofを使った作成があります。
初期値を指定しない作成方法は、長さを指定する方法としない方法があります。
a = new Array(3); console.log(a.length); // -> 3
a = []; console.log(a.length); // -> 0
初期値を指定する方法では、コンストラクタに指定する方法と、直接配列を定義する方法があります。
a = new Array(1,2,3); console.log(a); // -> [ 1, 2, 3 ]
a = [1,2,3]; console.log(a); // -> [ 1, 2, 3 ]
ofを使う場合は、引数に値を指定します。
a = Array.of(1, 2, 3); console.log(a); // -> [ 1, 2, 3 ]
連想配列は、オブジェクトにkeyとvalueを指定します。
o = {a:1, b:2, c:3}; console.log(o); // -> { a: 1, b: 2, c: 3 }
マップは、コンストラクタに配列形式で指定します。
m = new Map([ ['a', 1], ['b', 2], ['c', 3] ]); console.log(m); // -> Map { 'a' => 1, 'b' => 2, 'c' => 3 }
配列・リストから値を取得する
配列から値を取得するには、取得したい要素のインデックスを指定します。
a = [1,2,3]; r = a[0]; console.log(r); // -> 1
連想配列から値を取得には、取得したい要素のkeyを指定します。
o = {a:1, b:2, c:3}; r = o.a; console.log(r); // -> 1
マップから値を取得するには、getを使います。
m = new Map([ ['a', 1], ['b', 2], ['c', 3] ]); r = m.get('a'); console.log(r); // -> 1
配列・リストの長さ(要素数)を取得する
配列の長さを取得するには、lengthを使います。
a = [1,2,3]; r = a.length; console.log(r); // -> 3
連想配列の長さを取得するには、keysでkeyの配列を作成し、その後lengthで長さを取得します。
o = {a:1, b:2, c:3}; r = Object.keys(o).length; console.log(r); // -> 3
マップの長さを取得するには、sizeを使います。
m = new Map([ ['a', 1], ['b', 2], ['c', 3] ]); r = m.size; console.log(r); // -> 3
配列・リストに要素を追加する
配列の末尾に要素を追加するには、pushを使います。
a = [1,2,3]; a.push(4); console.log(a); // -> [ 1, 2, 3, 4 ]
配列の先頭に要素を追加するには、unshiftを使います。
a = [1,2,3]; a.unshift(4); console.log(a); // -> [ 4, 1, 2, 3 ]
配列の任意の場所に要素を追加するには、spliceを使います。
第1引数に追加するインデックス、第2引数は削除する要素数(今回は追加だけなので0を指定)、第3引数以降に追加したい要素を指定します。
a = [1,2,3]; a.splice(1,0,4); console.log(a); // -> [ 1, 4, 2, 3 ]
連想配列に要素を追加するには、直接keyを指定して値を追加します。
o = {a:1, b:2, c:3}; o.d = 4; console.log(o); // -> { a: 1, b: 2, c: 3, d: 4 }
Mapに要素を追加するには、setを使います。
m = new Map([ ['a', 1], ['b', 2], ['c', 3] ]); m.set('d', 4); console.log(m); // -> Map { 'a' => 1, 'b' => 2, 'c' => 3, 'd' => 4 }
配列・リストから要素を削除する
配列の先頭の要素を削除するには、shiftを使います。
a = [1,2,3]; a.shift(); console.log(a); // -> [ 2, 3 ]
配列の末尾の要素を削除するには、popを使います。
a = [1,2,3]; a.pop(); console.log(a); // -> [ 1, 2 ]
配列の任意の場所の要素を削除するには、spliceを使います。
第1引数に削除したい要素のインデックス、第2引数に削除したい要素数を指定します。
a = [1,2,3]; a.splice(1, 1); console.log(a); // -> [ 1, 3 ]
配列の要素をすべて削除するには、長さを0にします。
a = [1,2,3]; a.length = 0; console.log(a); // -> []
連想配列から要素を削除するには、deleteを使います。
o = {a:1, b:2, c:3}; delete o.a; console.log(o); // -> { b: 2, c: 3 }
Mapから要素を削除するには、deleteを使います。
m = new Map([ ['a', 1], ['b', 2], ['c', 3] ]); m.delete('a'); console.log(m); // -> Map { 'b' => 2, 'c' => 3 }
配列・リストをコピーする
配列をコピーするには、from、concat、slice、スプレッド構文を使う方法があります。
いずれの方法も、浅いコピー(シャローコピー)となります。
a = [1,2,3]; r = Array.from(a); console.log(r); // -> [ 1, 2, 3 ]
concatは、引数の結合対象を指定しないことで配列のコピーを作成します。
a = [1,2,3]; r = a.concat(); console.log(r); // -> [ 1, 2, 3 ]
sliceは、すべての要素を抽出することで配列のコピーを作成します。
a = [1,2,3]; r = a.slice(0); console.log(r); // -> [ 1, 2, 3 ]
スプレッド構文は、コピー先の配列作成時に、コピー元の配列を展開することでコピーを作成します。
a = [1,2,3]; r = [...a]; console.log(r); // -> [ 1, 2, 3 ]
連想配列のコピーは、assign、スプレッド構文を使う方法があります。
o = {a:1, b:2, c:3}; r = Object.assign({}, o); console.log(r); // -> { a: 1, b: 2, c: 3 }
o = {a:1, b:2, c:3}; r = {...o}; console.log(r); // -> { a: 1, b: 2, c: 3 }
配列・リストをループさせる
配列をループさせるには、for-of、forEachがあります。
単純にループさせるだけでなく、ループさせた要素に対して処理を行う場合には、map、filter、findなど別の方法もあります。
a = [1,2,3]; for(var r of a) { console.log(r); // -> 1 -> 2 -> 3 }
a = [1,2,3]; a.forEach((r) => { console.log(r); // -> 1 -> 2 -> 3 });
連想配列をループさせるには、for-ofにentriesを使う方法と、keysでkeyの配列を取得し、上記の配列の方法でループさせる方法があります。
o = {a:1, b:2, c:3}; for (const [key, value] of Object.entries(o)) { console.log(`${key} : ${value}`); // -> a : 1 -> b : 2 -> c : 3 }
Mapもfor-ofで同様にすることが可能です。
配列・リストの順番を入れ替える
配列の要素を入れ替えるには、sort、reverse、spliceを使います。
sortは、要素を文字列に変換し、UTF-16コード単位の値の並びに昇順でソートします。
a = [2,3,1]; r = a.sort(); console.log(r); // -> [ 1, 2, 3 ]
reverseは、要素を反転させます。
a = [1,2,3]; r = a.reverse(); console.log(r); // -> [ 3, 2, 1 ]
spliceは、削除と追加の指定によって、要素の順番を入れ替えます。
a = [1,2,3]; a.splice(1, 2, a[2], a[1]); // 2 と 3 を削除して、3 と 2 を追加 console.log(a); // -> [ 1, 3, 2 ]
連想配列やマップは順序がないので、入れ替えはありませんが、keyを配列に変換して入れ替えるということはできます。
配列・リスト同士を結合する
配列の結合は、concatを使います。
a1 = [1,2,3]; a2 = [4,5]; r = a1.concat(a2); console.log(r); // -> [ 1, 2, 3, 4, 5 ]
連想配列の結合は、assign、スプレッド構文を使用する方法があります。
o1 = {a:1, b:2, c:3}; o2 = {d:4, e:5}; r = Object.assign(o1, o2); console.log(r); // -> { a: 1, b: 2, c: 3, d: 4, e: 5 }
o1 = {a:1, b:2, c:3}; o2 = {d:4, e:5}; r = {...o1, ...o2}; console.log(r); // -> { a: 1, b: 2, c: 3, d: 4, e: 5 }
配列・リストを検索する
配列から特定の値を検索するには、includes、indexOfを使います。
includesは、配列の中に指定した値が含まれていればtrueを返し、含まれていない場合はfalseを返します。
a = [1,2,3]; r = a.includes(2); console.log(r); // -> true
indexOfは、配列の中に指定した値が含まれていれば、最初に見つかったインデックスを返します。
後方から検索する場合は、lastInfexOfを使います。
a = [1,2,3]; r = a.indexOf(2); console.log(r); // -> 1
連想配列の検索は、keyやvalueを配列に変換して、検索を行います。
配列・リストの操作はやりたい処理によって使うメソッドを変えよう
配列やリストの操作には、同じ結果を得られる方法が、処理を組み合わせることによって何通りもあります。
ですが、特にループの場合には、処理の仕方によってはパフォーマンスが悪いこともあります。
どんなメソッドを使うのかは、やりたい処理によって適宜変えられるように、日頃からたくさん引出しを持っておくことをおすすめします。
今回は、JavaScriptの配列・リスト操作についてまとめました。
参考になれば幸いです。
コメント