原文: JavaScript Array Insert - How to Add to an Array with the Push, Unshift, and Concat Functions
JavaScript の配列は筆者のお気に入りのデータ型です。動的で、使いやすく、多数の組み込みメソッドが提供されているからです。
しかし選択肢が多ければ多いほど、どれを使うべきか分かり辛くなることもあります。
この記事では、JavaScript の配列に要素を追加する一般的な方法をいくつか解説します。
配列への追加方法のインタラクティブな Scrim
(訳注: Scrimba というサイトの機能で、インタラクティブなエディタと動画がセットになっています。)
push メソッド
1 つ目の、そしておそらく最もよく見かけるであろう JavaScript 配列のメソッドは push() です。push() メソッドは、配列の末尾に要素を追加するために使われます。
ではここである配列を例に考えます。配列の各要素は、あなたがやらなければならないタスクを表す文字列になっているとしましょう。先にあったタスクから順に完了できるように、新しい要素は配列の末尾に追加するのが良いでしょう。
この例をコードで見てみましょう。
const arr = ['First item', 'Second item', 'Third item'];
arr.push('Fourth item');
console.log(arr); // ['First item', 'Second item', 'Third item', 'Fourth item']
push のおかげで、シンプルな構文で配列の末尾に要素を追加できました。
では一度に 2 つや 3 つの要素を追加したいとしましょう。その場合はどうしたらいいでしょうか?実は、push() は一度に複数の要素を受け取って追加することができます。
const arr = ['First item', 'Second item', 'Third item'];
arr.push('Fourth item', 'Fifth item');
console.log(arr); // ['First item', 'Second item', 'Third item', 'Fourth item', 'Fifth item']
では配列にいくつかタスクを追加できたところで、次は抱えているタスクが多すぎないかチェックするために、配列に要素がいくつあるか数えたいと思います。
幸いなことに、push() は戻り値として、要素を追加した後の配列の長さを返します。
const arr = ['First item', 'Second item', 'Third item'];
const arrLength = arr.push('Fourth item', 'Fifth item');
console.log(arrLength); // 5
console.log(arr); // ['First item', 'Second item', 'Third item', 'Fourth item', 'Fifth item']
unshift メソッド
すべてのタスクは平等に造られているとは限りません。配列にタスクを追加していく中で、突然他より緊急性の高いタスクが出てくることもあるでしょう。
そんな時に強い味方となる unshift() を紹介します。unshift() を使うと、配列の先頭に要素を追加することができます。
const arr = ['First item', 'Second item', 'Third item'];
const arrLength = arr.unshift('Urgent item 1', 'Urgent item 2');
console.log(arrLength); // 5
console.log(arr); // ['Urgent item 1', 'Urgent item 2', 'First item', 'Second item', 'Third item']
上記の例を見て気付いたかもしれませんが、push() メソッドと同様に unshift() も、追加後の配列の長さを返します。また、2 つ以上の要素を一度に追加することも可能です。
concat メソッド
concatenate (連結) の略である concat() メソッドは、2 つ以上の配列を連結するために使われます。
上で説明したように、unshift() メソッドと push() メソッドは追加後の配列の長さを返します。一方、concat() は真新しい配列を返します。
これは重要な特徴で、このため concat() は、変更 (mutate) したくない配列 (例えば React の state に保存されている配列) を扱う場合にとても便利です。
シンプルな使用例は次のようになります。
const arr1 = ['?', '?'];
const arr2 = ['?', '?'];
const arr3 = arr1.concat(arr2);
console.log(arr3); // ["?", "?", "?", "?"]
では連結したい配列が複数あるとしましょう。心配いりません。この場合も concat() が助けてくれます!
const arr1 = ['?', '?'];
const arr2 = ['?', '?'];
const arr3 = ['?', '?'];
const arr4 = arr1.concat(arr2,arr3);
console.log(arr4); // ["?", "?", "?", "?", "?", "?"]
理解を深めるためのインタラクティブな Scrim
concat を利用したクローン
concat() は既存の配列を変更したくない場合に役立つと言ったのを覚えていますか?この特徴を活用して、ある配列の中身を新しい配列へとコピーする方法を見ていきましょう。
const arr1 = ["?", "?", "?", "?", "?", "?"];
const arr2 = [].concat(arr1);
arr2.push("?");
console.log(arr1) //["?", "?", "?", "?", "?", "?"]
console.log(arr2) //["?", "?", "?", "?", "?", "?", "?"]
素晴らしい!このように、concat() を使って配列を "クローン" することができます。
しかし、この方法にはちょっとした落とし穴があります。新しい配列は、コピー元の配列の「シャローコピー (shallow copy)」です。つまりオブジェクトはすべて参照コピーで、実体のあるオブジェクトではありません。
もっと分かりやすく説明するために、例を見てみましょう。
const arr1 = [{food:"?"}, {food:"?"}, {food:"?"}]
const arr2 = [].concat(arr1);
// arr1 と arr2 両方が変更される
arr2[1].food = "!";
// arr2 だけが変更される
arr2.push({food:"*"})
console.log(arr1) // [ { food: '?' }, { food: '!' }, { food: '?' } ]
console.log(arr2) // [ { food: '?' }, { food: '!' }, { food: '?' }, { food: '*' } ]
元の配列を直接変更していないにもかかわらず、クローン後の配列に加えた変更によって、元の配列も影響されています。
配列を適切に "ディープクローン" する方法は複数ありますが、この記事では解説しませんので調べてみてください。
TL;DR
配列の末尾に要素を追加したい場合、push() を使います。配列の先頭に要素を追加する場合には unshift() を使います。そして複数の配列を連結するには concat() を使います。
もちろん、配列に要素を追加する方法は他にもたくさんあります。ぜひ自分でも調べて、便利な配列メソッドを見つけてください!
筆者の Twitter もありますのでお気軽にご連絡ください。要素の追加に使うお気に入りの配列メソッドなどもぜひ教えてください。