JavaScriptでArray.prototype.splice()を活用する10の方法

JavaScriptのArray.prototype.spliceメソッドを使いこなすための10の方法JS
この記事は約16分で読めます。

 

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

基本的な知識があればカスタムコードを使って機能追加、目的を達成できるように作ってあります。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を凌駕する現役のプログラマチームによって監修されています。

サイト内のコードを共有する場合は、参照元として引用して下さいますと幸いです

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

●Array.prototype.splice()とは?

JavaScriptを学び始めたばかりの頃、配列操作に戸惑った経験はありませんか?

特に、配列の要素を削除したり、置換したり、追加したりする際には、ついつい複雑な処理を書いてしまいがちです。

でも、そんな悩みを一発で解決してくれるのが、Array.prototype.splice()メソッドなんです。

splice()メソッドは、配列の要素を自在に操作できる強力なツールです。

しかも、構文がシンプルなので、初心者でも簡単に使いこなせるんですよ。

これさえマスターすれば、配列操作で困ることはないでしょう。

○splice()の構文と引数

splice()メソッドの構文は次のようになります。

array.splice(start, deleteCount, item1, item2, ...)

引数の意味を見ていきましょう。

  • start:操作を開始する位置のインデックス
  • deleteCount:startから削除する要素の数(省略可能)
  • item1, item2, …:startの位置に追加する要素(省略可能)

startは必須の引数ですが、deleteCountとitem1以降は省略可能です。

deleteCountを0にすれば、要素を削除せずに新しい要素を追加できますし、item1以降を指定しなければ、要素の削除だけを行えます。

○splice()の返り値

splice()メソッドは、削除された要素を含む新しい配列を返します。

これは、削除された要素を再利用したい場合に便利ですね。

○サンプルコード1:要素の削除

では、実際にsplice()メソッドを使って、配列の要素を削除してみましょう。

const fruits = ['apple', 'banana', 'orange', 'grape'];
const removedFruits = fruits.splice(1, 2);

console.log(fruits); // ['apple', 'grape']
console.log(removedFruits); // ['banana', 'orange']

このコードでは、fruitsの1番目のインデックスから2つの要素を削除しています。

削除された要素は、removedFruitsに格納されますね。

実行結果

['apple', 'grape']
['banana', 'orange']

○サンプルコード2:要素の置換

次は、splice()メソッドを使って、配列の要素を置換してみましょう。

const numbers = [1, 2, 3, 4, 5];
const removedNumbers = numbers.splice(2, 2, 10, 20);

console.log(numbers); // [1, 2, 10, 20, 5]
console.log(removedNumbers); // [3, 4]

このコードでは、numbersの2番目のインデックスから2つの要素を削除し、その位置に10と20を追加しています。

置換された要素は、removedNumbersに格納されます。

実行結果

[1, 2, 10, 20, 5]
[3, 4]

○サンプルコード3:要素の追加

最後に、splice()メソッドを使って、配列に要素を追加してみましょう。

const colors = ['red', 'green', 'blue'];
colors.splice(1, 0, 'yellow', 'purple');

console.log(colors); // ['red', 'yellow', 'purple', 'green', 'blue']

このコードでは、colorsの1番目のインデックスに、’yellow’と’purple’を追加しています。

deleteCountを0にしているので、要素は削除されません。

実行結果

['red', 'yellow', 'purple', 'green', 'blue']

どうでしたか?

splice()メソッドを使えば、配列の要素を自由自在に操作できることがわかったと思います。

ここからは、配列操作で悩むことはないはずです。次は、splice()メソッドの注意点について見ていきましょう。

●splice()の注意点

splice()メソッドは非常に便利ですが、いくつか注意点があります。

特に、破壊的メソッドであることと、負のインデックスの扱いには気をつけましょう。

この特性を理解しておかないと、意図しない結果を招くことがあるんです。

○破壊的メソッドであること

splice()メソッドは、元の配列を直接変更する破壊的メソッドです。

つまり、一度splice()を実行すると、もとの配列の状態は失われてしまうんですね。

これは、配列を操作する際に注意が必要なポイントです。

もし、元の配列を保持しておきたい場合は、splice()を実行する前に、配列のコピーを作成しておくことをおすすめします。

コピーを作成する方法はいくつかありますが、よく使われるのがslice()メソッドですね。

○負のインデックスの扱い

splice()メソッドでは、startに負の値を指定することができます。

負の値を指定した場合、配列の末尾からのインデックスとして解釈されます。

例えば、-1を指定すると、配列の最後の要素を表すんです。

ただし、負のインデックスを使う場合は、配列のインデックスが0から始まることに注意が必要です。

つまり、-1は配列の最後の要素を表しますが、-0は0と同じで、配列の最初の要素を表すんですね。

○サンプルコード4:負のインデックスを使った要素削除

では、負のインデックスを使って、配列の要素を削除してみましょう。

const fruits = ['apple', 'banana', 'orange', 'grape'];
const removedFruits = fruits.splice(-2, 1);

console.log(fruits); // ['apple', 'banana', 'grape']
console.log(removedFruits); // ['orange']

このコードでは、fruitsの最後から2番目の要素(’orange’)を削除しています。

負のインデックスを使うことで、配列の末尾からの位置を指定できるんです。

実行結果

['apple', 'banana', 'grape']
['orange']

○サンプルコード5:要素数より大きな deleteCount の扱い

splice()メソッドのdeleteCountに、startからの残りの要素数より大きな値を指定するとどうなるでしょうか?

実は、startから配列の末尾までのすべての要素が削除されるんです。

const numbers = [1, 2, 3, 4, 5];
const removedNumbers = numbers.splice(2, 10);

console.log(numbers); // [1, 2]
console.log(removedNumbers); // [3, 4, 5]

このコードでは、numbersの2番目のインデックスから10個の要素を削除しようとしています。

しかし、実際には2番目以降のすべての要素が削除されますね。

実行結果

[1, 2]
[3, 4, 5]

●splice()の応用テクニック

さて、splice()メソッドの基本的な使い方や注意点については理解が深まったと思います。

ここからは、もう一歩踏み込んで、splice()メソッドの応用テクニックを見ていきましょう。

配列操作のプロフェッショナルを目指すために、ぜひマスターしておきたい テクニックばかりですよ。

○サンプルコード6:配列の切り詰め

splice()メソッドを使えば、配列の切り詰めも簡単にできます。

つまり、配列の一部を取り出して、新しい配列を作成するんですね。

const numbers = [1, 2, 3, 4, 5];
const slicedNumbers = numbers.splice(0, 3);

console.log(numbers); // [4, 5]
console.log(slicedNumbers); // [1, 2, 3]

このコードでは、numbersの先頭から3つの要素を取り出して、slicedNumbersに代入しています。

もとのnumbersからは、取り出された要素が削除されますね。

実行結果

[4, 5]
[1, 2, 3]

○サンプルコード7:配列の結合

splice()メソッドを使って、2つの配列を結合することもできます。

const array1 = [1, 2, 3];
const array2 = [4, 5, 6];

array1.splice(array1.length, 0, ...array2);

console.log(array1); // [1, 2, 3, 4, 5, 6]

このコードでは、array1の末尾に、array2の要素を追加しています。

スプレッド構文(…)を使うことで、array2の要素を個別の引数として渡せるんです。

実行結果

[1, 2, 3, 4, 5, 6]

○サンプルコード8:配列のシャッフル

splice()メソッドを使えば、配列の要素をランダムにシャッフルすることもできます。

const array = [1, 2, 3, 4, 5];

for (let i = array.length - 1; i > 0; i--) {
  const j = Math.floor(Math.random() * (i + 1));
  [array[i], array[j]] = [array[j], array[i]];
}

console.log(array); // [3, 1, 5, 2, 4] (ランダムな順序)

このコードでは、Fisher-Yatesのシャッフルアルゴリズムを使って、配列の要素をランダムに並び替えています。

splice()メソッドを使わずに、配列の要素を直接入れ替えているんですね。

実行結果

[3, 1, 5, 2, 4] (ランダムな順序)

○サンプルコード9:重複要素の削除

splice()メソッドを使って、配列から重複する要素を削除することもできます。

const array = [1, 2, 3, 1, 2, 3, 4, 5];

for (let i = 0; i < array.length; i++) {
  if (array.indexOf(array[i]) !== i) {
    array.splice(i, 1);
    i--;
  }
}

console.log(array); // [1, 2, 3, 4, 5]

このコードでは、配列を先頭から順に走査し、現在の要素のインデックスと、その要素が最初に現れるインデックスが一致しない場合、その要素を削除しています。

これにより、重複する要素が取り除かれるんですね。

実行結果:

[1, 2, 3, 4, 5]

○サンプルコード10:条件に基づく要素の削除

splice()メソッドを使えば、特定の条件に基づいて要素を削除することもできます。

const array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

for (let i = 0; i < array.length; i++) {
  if (array[i] % 2 === 0) {
    array.splice(i, 1);
    i--;
  }
}

console.log(array); // [1, 3, 5, 7, 9]

このコードでは、配列から偶数の要素をすべて削除しています。

splice()メソッドで要素を削除すると、配列のインデックスがずれるので、iをデクリメントして調整しているんですね。

実行結果

[1, 3, 5, 7, 9]

●splice()と他のメソッドの組み合わせ

さて、ここまでsplice()メソッドの基本から応用までを見てきましたが、実際の開発では、splice()メソッドを他のメソッドと組み合わせて使うことも多いですよね。

そうすることで、より効率的で可読性の高いコードを書くことができるんです。

splice()メソッドと相性のいいメソッドといえば、filter()、map()、reduce()などが挙げられます。

このメソッドと組み合わせることで、配列の要素を柔軟に操作できるようになりますよ。

○filter()との組み合わせ

filter()メソッドは、配列の要素をテストし、条件に合致する要素だけを抽出して新しい配列を作成します。

これをsplice()メソッドと組み合わせることで、条件に合致する要素を削除することができるんです。

const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

const oddNumbers = numbers.filter((num, index) => {
  if (num % 2 !== 0) {
    numbers.splice(index, 1);
    return true;
  }
  return false;
});

console.log(numbers); // [2, 4, 6, 8, 10]
console.log(oddNumbers); // [1, 3, 5, 7, 9]

このコードでは、filter()メソッドを使って、numbersから奇数の要素を抽出しています。

同時に、splice()メソッドを使って、抽出された要素をnumbersから削除しているんですね。

実行結果

[2, 4, 6, 8, 10]
[1, 3, 5, 7, 9]

○map()との組み合わせ

map()メソッドは、配列の要素を変換して、新しい配列を作成します。

これをsplice()メソッドと組み合わせることで、要素を変換しながら、不要な要素を削除することができるんです。

const numbers = [1, 2, 3, 4, 5];

const doubledNumbers = numbers.map((num, index) => {
  if (num % 2 === 0) {
    numbers.splice(index, 1);
    return num * 2;
  }
  return num;
});

console.log(numbers); // [1, 3, 5]
console.log(doubledNumbers); // [1, 4, 3, 8, 5]

このコードでは、map()メソッドを使って、numbersの偶数の要素を2倍にしています。

同時に、splice()メソッドを使って、元の偶数の要素をnumbersから削除しているんですね。

実行結果

[1, 3, 5]
[1, 4, 3, 8, 5]

○reduce()との組み合わせ

reduce()メソッドは、配列の要素を累積的に処理し、単一の値を返します。

これをsplice()メソッドと組み合わせることで、要素を処理しながら、不要な要素を削除することができるんです。

const numbers = [1, 2, 3, 4, 5];

const sum = numbers.reduce((acc, num, index) => {
  if (num % 2 === 0) {
    numbers.splice(index, 1);
  }
  return acc + num;
}, 0);

console.log(numbers); // [1, 3, 5]
console.log(sum); // 9

このコードでは、reduce()メソッドを使って、numbersの要素の合計値を計算しています。

同時に、splice()メソッドを使って、偶数の要素をnumbersから削除しているんですね。

実行結果

[1, 3, 5]
9

●よくあるエラーと対処法

splice()メソッドを使っていると、時々エラーに遭遇することがありますよね。

でも、エラーメッセージを見ただけでは、何が問題なのかわからないこともあるんです。

ここでは、splice()メソッドを使う際によくあるエラーと、その対処法を見ていきましょう。

○TypeError: Cannot read property ‘splice’ of undefined

このエラーは、splice()メソッドを呼び出そうとしている対象が、undefinedであることを示しています。

つまり、配列ではないオブジェクトに対してsplice()メソッドを呼び出そうとしているんですね。

let array;
array.splice(0, 1); // TypeError: Cannot read property 'splice' of undefined

このエラーを避けるには、splice()メソッドを呼び出す前に、対象が配列であることを確認しましょう。

例えば、次のようにif文を使って、配列かどうかをチェックできます。

let array;
if (Array.isArray(array)) {
  array.splice(0, 1);
}

○RangeError: Invalid array length

このエラーは、splice()メソッドの引数に、配列のインデックスの範囲を超える値を指定した場合に発生します。

例えば、要素数が5の配列に対して、インデックス10から要素を削除しようとすると、このエラーが発生するんです。

const array = [1, 2, 3, 4, 5];
array.splice(10, 1); // RangeError: Invalid array length

このエラーを避けるには、splice()メソッドの引数に、配列のインデックスの範囲内の値を指定するようにしましょう。

例えば、次のように配列の長さを超えないようにします。

const array = [1, 2, 3, 4, 5];
if (10 < array.length) {
  array.splice(10, 1);
}

○配列が意図した通りに変更されない場合

splice()メソッドを使っても、配列が意図した通りに変更されないことがあります。

その原因の多くは、splice()メソッドの引数の指定ミスです。

例えば、要素を追加しようとしているのに、第2引数(deleteCount)に0以外の値を指定してしまうと、要素が削除されてしまうんです。

const array = [1, 2, 3];
array.splice(1, 1, 4, 5); // [1, 4, 5]

このコードでは、インデックス1の位置に要素を追加しようとしていますが、第2引数に1を指定しているため、インデックス1の要素が削除されています。

まとめ

splice()メソッドは、JavaScriptの配列操作において非常に重要な役割を果たします。

要素の削除、置換、追加を柔軟に行えるため、配列のデータを自在に manipulate できます。

ただし、splice()メソッドは破壊的であるため、使用には注意が必要ですね。

今回は、splice()メソッドの基本的な使い方から、応用的なテクニック、他のメソッドとの組み合わせ、よくあるエラーの対処法まで、幅広く解説してきました。

サンプルコードを交えながら、具体的な使用例を示すことで、理解が深まったのではないでしょうか。

splice()メソッドを効果的に使いこなすことで、コードの可読性と効率が向上し、より洗練された配列操作が可能になります。

初心者の方も、ベテランエンジニアの方も、ぜひsplice()メソッドをマスターして、JavaScriptでの配列操作のスキルを磨いてくださいね。