splice(削除)とは何か
splice は「配列の途中から指定した数だけ要素を削除する」ためのメソッドです。書式は array.splice(start, deleteCount, ...insertItems) ですが、今回は削除に集中します。ここが重要です:splice は“破壊的操作”。元の配列を直接書き換え、戻り値として「削除された要素の配列」を返します。削除位置は 0 始まりのインデックス、範囲は start から deleteCount 件です。
基本の削除と戻り値
位置と件数を指定して削除する
const a = ["A", "B", "C", "D"];
const removed = a.splice(1, 2); // 1番目から2件削除
console.log(a); // ["A", "D"](元配列が更新される)
console.log(removed); // ["B", "C"](戻り値は削除された要素)
JavaScriptここが重要です:start は「削除を始める位置」、deleteCount は「削除する件数」。戻り値は“削除された実体”を確認・再利用するのに便利です。
末尾まで削除(deleteCount を省略)
const b = [1, 2, 3, 4, 5];
b.splice(2); // 2番目から末尾まで削除(deleteCount 省略)
console.log(b); // [1, 2]
JavaScriptここが重要です:deleteCount を省略すると「開始位置から最後まで」を削除します。部分的に切り詰めたいときの最短手です。
よく使う削除パターン(安全に、意図通り)
値を探してから削除(findIndex と合わせる定番)
const items = ["pen", "book", "note"];
const i = items.findIndex(x => x === "book");
if (i !== -1) items.splice(i, 1);
console.log(items); // ["pen", "note"]
JavaScriptここが重要です:まず位置を探し、見つかったときだけ削除する。-1 の判定を忘れないことで「存在しないものを削る」事故を防げます。
重複がある場合の削除(最初の1件だけ)
const list = ["A", "B", "A"];
const i = list.indexOf("A");
if (i !== -1) list.splice(i, 1);
console.log(list); // ["B", "A"]
JavaScriptここが重要です:indexOf は“最初の位置”。重複をすべて消したいなら filter の方が簡潔(後述)です。
範囲削除(複数の連続要素)
const nums = [0, 1, 2, 3, 4, 5];
nums.splice(2, 3); // 2,3,4 を削除
console.log(nums); // [0, 1, 5]
JavaScriptここが重要です:連続範囲をまとめて消すのが splice の得意技。開始と件数を正しく指定すれば一撃で整理できます。
負のインデックス・境界条件・微妙な仕様
負の start(後ろからの位置指定)
const a = ["A","B","C","D"];
a.splice(-2, 1); // 最後から2番目("C")を1件削除
console.log(a); // ["A","B","D"]
JavaScriptここが重要です:start に負の値を渡すと「末尾から数える」。-1 は最後の要素、-2 は最後から2番目です。可読性が上がり、末尾付近の操作が直感的になります。
start が範囲外、deleteCount の調整
const a = ["X","Y"];
a.splice(99, 1); // 何も削除されない(範囲外開始)
a.splice(1, 99); // 1番目から残り全部削除(件数は自動で切り詰め)
JavaScriptここが重要です:start が配列長以上なら削除なし。deleteCount は「残り要素数」を超えても安全に切り詰められます。
deleteCount が 0(削除しない)
const a = ["A","B","C"];
const removed = a.splice(1, 0); // 削除数 0
console.log(a); // 変化なし
console.log(removed); // []
JavaScriptここが重要です:削除なし。挿入を組み合わせるときに使いますが、削除だけなら 0 は意味がないので避けましょう。
破壊的操作の注意と“非破壊”で同じ効果を得る
共有参照の副作用に注意
const original = ["A","B","C"];
const alias = original; // 同じ配列参照
original.splice(1, 1);
console.log(alias); // ["A","C"](同時に変わる)
JavaScriptここが重要です:splice は元配列を壊します。状態管理(React/Vue)や共有前提では副作用の原因になるため、非破壊の代替が安全です。
非破壊で“削除後の形”を作る(filter と slice+スプレッド)
// 条件削除(全部対象)
const xs = [1,2,3,4];
const withoutEven = xs.filter(x => x % 2 !== 0); // 偶数を削除 → [1,3]
// 位置削除(1件)
const ys = ["A","B","C","D"];
const i = 2;
const removed1 = [...ys.slice(0, i), ...ys.slice(i + 1)]; // ["A","B","D"]
// 位置削除(範囲)
const start = 1, count = 2;
const removedRange = [...ys.slice(0, start), ...ys.slice(start + count)];
JavaScriptここが重要です:filter は“条件で残す”、slice+スプレッドは“位置指定で除く”。どちらも元配列はそのまま、差分検知にも素直です。
実践例(IDで削除・複数条件・末尾近辺)
ID で1件削除(見つけてから安全に)
const users = [{id:1},{id:2},{id:3}];
const i = users.findIndex(u => u.id === 2);
if (i !== -1) users.splice(i, 1);
JavaScriptここが重要です:findIndex は「条件で位置を見つける」最短手。存在チェック→削除で事故を防げます。
条件に合う連続区間を削除(開始位置を探す)
const temps = [18, 19, 40, 41, 20];
const start = temps.findIndex(t => t >= 40);
if (start !== -1) temps.splice(start, 2); // 40,41 を削除
JavaScriptここが重要です:連続区間なら開始位置+件数でまとめて消すとシンプルです。
末尾近辺を削る(負の start が便利)
const a = ["A","B","C","D","E"];
a.splice(-3, 2); // 最後から3番目を起点に2件削除 → "C","D" を削除
console.log(a); // ["A","B","E"]
JavaScriptここが重要です:末尾指向の削除では負のインデックスが読みやすく、境界ミスを減らせます。
よくある落とし穴と回避策
削除前に位置確認をせず splice(-1, 1) などを乱用すると、意図しない要素を消しがちです。必ず「何を消すのか」を明示(findIndex や indexOf)してから削除しましょう。複数削除をループで splice すると、インデックスが詰まってずれていき、次の削除位置が変わるバグが起こります。後ろから前へ削除する、または非破壊の filter に切り替えると安全です。状態共有(参照共有)のまま splice を使うと、他のロジックや UI に副作用が伝播します。非破壊の代替(filter、slice+スプレッド)へ切り替えましょう。deleteCount を省略した結果「末尾まで全部消えた」事故が起こります。省略時の挙動を理解し、意図した件数を必ず指定してください。
まとめ
splice(削除)は「開始位置と件数」を指定して、配列を直接書き換えながら削除し、削除された要素の配列を返します。負のインデックスで末尾指向の操作が直感的になり、deleteCount 省略で「末尾まで」削除できます。副作用を避けたい場面では filter(条件で残す)や slice+スプレッド(位置で除く)で非破壊に同じ結果を得るのが安全。削除前に“位置を確定”し、複数削除のインデックスずれを避ける——この基本を徹底すれば、初心者でも意図通りで壊れにくい削除が書けます。
