【Javascript】 配列
Javascriptにおける配列は、単なる配列を保存するだけでなく、mapやfilterなど、便利なメソッドが揃っています。
目次
配列の作り方
const a = [1, 2, 3] const b = [1, [20, 30], [100, 200, 300]] // 最大2次元の配列
[]
で囲み、その中に要素をカンマ区切りで入れることで、配列を作っています。
配列の値を利用する方法は他言語と同じです。
件数の取得
.length
を用います。
const a = [1, 2, 3]; for (let i = 0; i < a.length; i++) { // ... }
代入
配列の代入では、参照が代入されます。
const a = [3, 5, 1, 9, 3]; const b = a; // 配列本体はコピーされず, 参照の値が代入される b[3] = 100; console.log(a); console.log(b);
[ 3, 5, 1, 100, 3 ] [ 3, 5, 1, 100, 3 ]
1段階目までのコピーはスプレッド構文を、それ以上のディープコピーはいくつか方法があります。(後述)
配列の操作
末尾に要素の追加(push)
末尾に追加するには、push
を使います。
const a = [1, 2, 3]; a.push(100); console.log(a);
[ 1, 2, 3, 100 ]
末尾の要素の削除(pop)
末尾の要素の削除は、pop
を使います。
pop
すると同時に、その削除した値が戻り値として返されます。
const a = [1, 2, 3]; const v = a.pop(); console.log(v); console.log(a);
3 [ 1, 2 ]
要素の挿入と削除(splice)
splice
を用います。このメソッドは、追加と削除両方の操作が可能です。
push
とpop
では対応できない場合に用います。
splice(場所指定, 消す数, 追加する要素)
です。要素の追加では、指定したインデックスの直前に追加されます。
追加
削除する数を0とすれば、追加のみが可能です。
const x = [1, 2, 3]; x.splice(2, 0, 100); console.log(x);
[ 1, 2, 100, 3 ]
この場合、2番目のインデックスの直前に100
を追加します。
削除
削除する数を設定します。ここで、追加する要素の引数には何も与えないようにします。
const x = [1, 2, 3]; x.splice(1, 1); console.log(x);
[ 1, 3 ]
この場合、1番目のインデックスを始点として、1個削除しています。
連結(concat)
concat
で連結します。
const a = [1, 2, 3]; const b = [4, 5, 6]; console.log(a.concat(b));
[ 1, 2, 3, 4, 5, 6 ]
引数に入れた配列が後ろに連結されます。
連結(スプレッド構文)
スプレッド構文でも同様に連結できます。
スプレッド構文はこのあとのセクションにあります。
const a = [1, 2, 3]; const b = [4, 5, 6]; console.log([...a, ...b]);
[ 1, 2, 3, 4, 5, 6 ]
もちろん、b = [...a, 4, 5, 6];
のようにも連結できます。
ソート(sort)
sort
を利用します。
const a = [3, 5, 1, 9, 3]; a.sort(); console.log(a);
[ 1, 3, 3, 5, 9 ]
中に連想配列を保つ場合、第2引数に、どのように比較するかを関数で指定します。
let a = [ {i: 5}, {i: 10}, {i: 1}, {i: 9}, ] a.sort((lhs, rhs) => { return lhs.i - rhs.i; // 正負を入れ替えれば降順になる }); console.log(a);
[ { i: 1 }, { i: 5 }, { i: 9 }, { i: 10 } ]
この書き方はコールバックを利用しています。
sort
の第1引数に、比較用の関数を与えます。要素を比較するとき、左辺<右辺なら負数、左辺==右辺なら0
、左辺>右辺なら正数を返すと昇順ソートになります。
比較用関数には引数が2つあり、これは比較しようとしている配列の要素です。
lhsはLeft-hand sideの頭文字を取ったもので、左辺という意味です。rhsも同様にRight-hand sideの頭文字で、右辺の意味です。
非破壊なソート
上のソートでは、元の配列が変化してしまします。そこで、1段目をコピーすることでその破壊を防ぎます。
const a = [3, 5, 1, 9, 3]; const b = [...a].sort(); console.log(a); console.log(b);
[ 3, 5, 1, 9, 3 ] [ 1, 3, 3, 5, 9 ]
スプレッド構文
Javascriptの配列を一旦解体するには、スプレッド構文を用います。
let a = [1, 2, 3]; let b = [100, 200, ...a]; console.log(b);
[100, 200, 1, 2, 3]
function hoge(a, b, c) { return a + b + c; } let a = [1, 2, 3] console.log(hoge(...a));
6
スプレッド構文は、解体した配列の行き先が存在している必要があるのと、次のような使えそうで使えない場面があります。
const a = [1, 2, 3]; const h, i, j = ...a; // Uncaught SyntaxError: Unexpected token '...'
しかし、配列の連結、実引数への変形など、使えれば非常に簡潔に書くことができます。
ディープコピー
1段階目だけなら、スプレッド構文で簡単にコピーできます。しかし、それより深いなら別の方法になります。
let a = [1, 2, 3, [4, 5, 6]]; let b = [...a]; // スプレッド構文 b[2] = 40; b[3][0] = 100; console.log(a); console.log(b);
[1, 2, 3, [100, 5, 6]] [1, 2, 40, [100, 5, 6]]
...a
では、a
の値を展開するという動作をします。つまり、[1, 2, 3]
だったものは実質1, 2, 3
になります。
ライブラリを用いる
例えば、lodashなどを用います。
仮に自前で実装するとすれば、DFSなどを用いることになると思います。
const _ = require('lodash'); const a = [ 1, 2, [11, 12], [ 21, 22, [231, 232, 233], ] ]; const b = _.cloneDeep(a); b[1] = 100; b[2][0] = 4500; b[3][2][1] = 1000; console.log(a); console.log(b);
[ 1, 2, [ 11, 12 ], [ 21, 22, [ 231, 232, 233 ] ] ] [ 1, 100, [ 4500, 12 ], [ 21, 22, [ 231, 1000, 233 ] ] ]
深い階層までしっかりコピーされていることがわかります。
走査する方法
Javascriptでは、単純なfor (let i = 0; ...) {}
だけでなく、すべての要素を見るいくつかの方法があります。
詳しくは下のページにまとめてあります。
まとめ
配列の操作でよく利用するメソッドを紹介しました。とくにpush
は非常に利用頻度が高いです。
配列操作はどの言語でも割と似ているので、比較的すぐに覚えることができるのではないでしょうか。
