何をしたいユーティリティか:「要素削除」
「要素削除」は、配列から特定の要素を取り除く処理です。
「このインデックスの要素を消したい」「この値を全部消したい」「条件に合うものだけ消したい」など、業務でめちゃくちゃよく出てきます。
ここで一番大事なのは、次の2点です。
元の配列を壊すか(破壊的)、壊さないか(非破壊的)を決めること。
「何を基準に削除するか」(インデックス・値・条件)をはっきりさせること。
業務ユーティリティとしては、基本は「非破壊」で書くのがおすすめです。
インデックス指定で削除する removeAt(非破壊)
基本の形
「この位置の要素を1つ消したい」という一番シンプルなパターンです。
function removeAt(array, index) {
if (!Array.isArray(array)) {
return [];
}
const len = array.length;
if (index < 0 || index >= len) {
return array.slice();
}
const head = array.slice(0, index);
const tail = array.slice(index + 1);
return [...head, ...tail];
}
JavaScript重要ポイントの解説
まず Array.isArray で配列かどうかをチェックし、違ったら空配列を返します。
インデックスが範囲外(0 未満、または length 以上)の場合は、何も削除せずにコピーだけ返します。slice(0, index) で「削除対象より前」、slice(index + 1) で「削除対象より後ろ」を取り出し、[...head, ...tail] でつなげて「削除済みの新しい配列」を作ります。
元の配列は一切変更されません。
動作例
const arr = [10, 20, 30, 40];
const r1 = removeAt(arr, 1); // 20 を削除
// [10, 30, 40]
const r2 = removeAt(arr, 0); // 10 を削除
// [20, 30, 40]
const r3 = removeAt(arr, 10); // 範囲外 → そのままコピー
// [10, 20, 30, 40]
console.log(arr); // [10, 20, 30, 40](元は変わらない)
JavaScript値で削除する removeValue / removeAll
最初に見つかった1件だけ削除する removeValue
「この値に一致する最初の1件だけ消したい」パターンです。
function removeValue(array, value) {
if (!Array.isArray(array)) {
return [];
}
const index = array.indexOf(value);
if (index === -1) {
return array.slice();
}
return removeAt(array, index);
}
JavaScriptindexOf で最初に見つかった位置を取り、見つからなければコピーだけ返します。
見つかったら removeAt を使って、その位置の要素を削除した新しい配列を返します。
動作イメージはこうです。
const arr = ["a", "b", "c", "b"];
const r1 = removeValue(arr, "b");
// ["a", "c", "b"](最初の b だけ削除)
const r2 = removeValue(arr, "x");
// ["a", "b", "c", "b"](見つからないのでそのまま)
JavaScript一致するものを全部削除する removeAll
「この値に一致する要素を全部消したい」パターンです。
function removeAll(array, value) {
if (!Array.isArray(array)) {
return [];
}
return array.filter((item) => item !== value);
}
JavaScriptfilter は「条件を満たすものだけ残す」ので、
「value と等しくないものだけ残す」=「value と等しいものを全部削除する」になります。
動作例:
const arr = ["a", "b", "c", "b"];
const r = removeAll(arr, "b");
// ["a", "c"]
console.log(arr); // ["a", "b", "c", "b"](元は変わらない)
JavaScript条件で削除する removeIf(業務で一番使いやすい形)
predicate(条件関数)で削除対象を決める
業務では、「id が一致するものを消したい」「フラグが true のものだけ消したい」など、
単純な値一致ではなく「条件」で削除したいことが多いです。
function removeIf(array, predicate) {
if (!Array.isArray(array)) {
return [];
}
if (typeof predicate !== "function") {
return array.slice();
}
return array.filter((item, index) => !predicate(item, index));
}
JavaScriptここでは、「predicate が true を返した要素を削除する」というルールにしています。filter で「!predicate(…)」を残すことで、「条件に合うものを除外」しているイメージです。
動作例:id が一致する要素を削除
const users = [
{ id: 1, name: "A" },
{ id: 2, name: "B" },
{ id: 3, name: "C" },
];
const result = removeIf(users, (u) => u.id === 2);
/*
[
{ id: 1, name: "A" },
{ id: 3, name: "C" },
]
*/
JavaScript「id=2 のユーザーを削除する」という業務的な操作が、一行で書けます。
破壊的な splice とどう付き合うか
splice の問題点
JavaScript には splice という「その場で配列を書き換える削除」があります。
const arr = [10, 20, 30, 40];
arr.splice(1, 2); // インデックス1から2件削除
console.log(arr); // [10, 40]
JavaScript便利ですが、元の配列が書き換わるのが大きなクセです。
業務コードでこれを多用すると、
どこかで配列が勝手に短くなっている。
別の処理が想定外の順番・要素数で動き始める。
といったバグにつながりやすくなります。
ユーティリティで「非破壊」を標準にする
removeAt / removeValue / removeAll / removeIf のように、
「必ず新しい配列を返す」「元の配列は変えない」というスタイルをユーティリティで固定しておくと、
「配列がいつどこで変わったのか分からない」問題がかなり減ります。
どうしてもパフォーマンスなどの理由で破壊的にやりたいときだけ、
「ここは意図的に splice を使う」と明示して書く、という方針が安全です。
手を動かして感覚をつかむ
コンソールで、次のコードを実際に打ってみてください。
function removeAt(array, index) {
if (!Array.isArray(array)) return [];
const len = array.length;
if (index < 0 || index >= len) return array.slice();
const head = array.slice(0, index);
const tail = array.slice(index + 1);
return [...head, ...tail];
}
function removeValue(array, value) {
if (!Array.isArray(array)) return [];
const index = array.indexOf(value);
if (index === -1) return array.slice();
return removeAt(array, index);
}
function removeAll(array, value) {
if (!Array.isArray(array)) return [];
return array.filter((item) => item !== value);
}
function removeIf(array, predicate) {
if (!Array.isArray(array)) return [];
if (typeof predicate !== "function") return array.slice();
return array.filter((item, index) => !predicate(item, index));
}
const arr = [10, 20, 30, 40, 20];
console.log(removeAt(arr, 2)); // [10, 20, 40, 20]
console.log(removeValue(arr, 20)); // [10, 30, 40, 20]
console.log(removeAll(arr, 20)); // [10, 30, 40]
console.log(removeIf(arr, (v) => v >= 30)); // [10, 20, 20]
console.log(arr); // [10, 20, 30, 40, 20]
JavaScript「どの削除がどう効いているか」「元の配列が変わっていないこと」を、自分の目で確認してみてください。
まとめ:要素削除ユーティリティを“標準の削除手段”にする
業務コードでは、配列から要素を消す場面が本当に多いです。
そのたびに splice や filter を直書きするのではなく、
export function removeAt(...) { ... }
export function removeValue(...) { ... }
export function removeAll(...) { ... }
export function removeIf(...) { ... }
JavaScriptのようなユーティリティを用意して、「配列から要素を削除したいときは必ずこれを通す」と決めておくと、
削除ロジックが統一されて、バグも読みづらさも一気に減ります。
「何を基準に削除するか」と「元配列を壊すかどうか」を、
毎回意識的に選べるようになることが、配列操作を“業務レベル”に引き上げるポイントです。
