配列内存在チェックとは何か
「配列内存在チェック」は、ある値や条件に合う要素が配列に含まれているかどうかを判定することです。ここが重要です:何を知りたいかで使うメソッドが変わります。「あるかどうかだけ」なら true/false を返すメソッド、「どこにあるか」まで知りたいなら位置(インデックス)を返すメソッドを選びます。値そのものの一致と、条件式での一致も使い分けましょう。
値の存在だけ判定する(includes)
基本の存在判定
const a = ["pen", "book", "note"];
console.log(a.includes("book")); // true
console.log(a.includes("pencil")); // false
JavaScriptここが重要です:位置は不要で「あるかどうか」だけ知りたいなら includes が最短です。厳密等価に近い比較で、型も比較されます(”2″ と 2 は別)。
NaN を正しく検出できる
console.log([NaN].includes(NaN)); // true
JavaScriptここが重要です:indexOf は NaN を見つけられませんが、includes は検出できます。数値計算の異常値混入チェックに有用です。
検索開始位置(fromIndex)
const a = ["A", "B", "A", "C"];
console.log(a.includes("A", 2)); // true(インデックス2以降に "A" がある)
console.log(a.includes("B", 2)); // false(2以降には "B" がない)
JavaScriptここが重要です:重複がある配列で「後ろ側に存在するか」を判定できます。負の値は末尾からの相対位置です。
位置が欲しいとき(indexOf/lastIndexOf)
最初の位置を取る(indexOf)
const a = ["A", "B", "A"];
console.log(a.indexOf("A")); // 0(最初の位置)
JavaScriptここが重要です:見つからなければ -1。削除や置換に使うときは必ず i >= 0 を確認してから操作します。
最後の位置を取る(lastIndexOf)
const a = ["A", "B", "A"];
console.log(a.lastIndexOf("A")); // 2(最後の位置)
JavaScriptここが重要です:重複の「最後だけ」を扱いたいときに便利。fromIndex で「ここから後ろ向きに」検索できます。
NaN と型・参照の注意
[NaN].indexOf(NaN); // -1(見つからない)
[NaN].includes(NaN); // true(見つかる)
const obj = { id: 1 };
const a = [obj, { id: 1 }];
a.indexOf(obj); // 0(同じ参照は一致)
a.indexOf({ id: 1 }); // -1(別インスタンスは不一致)
JavaScriptここが重要です:indexOf/lastIndexOf は NaN を見つけられません。オブジェクトは“同じ参照”のみ一致します。
条件で存在を判定する(some/find/findIndex)
条件が“1つでも”満たされるか(some)
const users = [{id:1},{id:2}];
const exists = users.some(u => u.id === 2); // true
JavaScriptここが重要です:true/false だけが欲しいなら some。最初に一致したら即停止するので効率的です。
最初の一致“要素”が欲しい(find)
const users = [{id:1},{id:2},{id:2}];
const user = users.find(u => u.id === 2);
console.log(user); // {id:2}(最初の一致)
JavaScriptここが重要です:見つからなければ undefined。要素を取得して使う用途に向いています。
最初の一致“位置”が欲しい(findIndex)
const users = [{id:1},{id:2}];
const i = users.findIndex(u => u.id === 2);
console.log(i); // 1(見つからなければ -1)
JavaScriptここが重要です:削除・置換など位置ベースの操作に最適です。-1 チェックは必ず行います。
よくある現場のパターン(重複防止・ホワイトリスト・トグル)
重複を防いで追加(非破壊)
const tags = ["js", "web"];
const next = tags.includes("ux") ? tags : [...tags, "ux"];
// → ["js","web","ux"]
JavaScriptここが重要です:存在判定で分岐すると、重複追加を簡単に防げます。非破壊更新は UI の差分検知とも相性が良いです。
ホワイトリストで入力検証
const allow = ["png", "jpg", "gif"];
function isAllowed(ext) {
return allow.includes(ext.toLowerCase());
}
JavaScriptここが重要です:大小は区別されるため、事前に小文字化するなど正規化してから判定します。
トグル(あるなら外す、なければ足す)
function toggle(arr, value) {
return arr.some(x => x === value)
? arr.filter(x => x !== value)
: [...arr, value];
}
JavaScriptここが重要です:some を軸に追加・削除を切り替えると読みやすく、副作用のないロジックになります。
文字列の大小・部分一致・性能の注意
大文字小文字は区別される
const tags = ["JS", "web"];
tags.includes("js"); // false
const norm = tags.map(t => t.toLowerCase());
norm.includes("js"); // true
JavaScriptここが重要です:意図どおりの比較をするために、大小や形式を合わせてから判定します。
部分一致はしない(完全一致のみ)
const a = ["hello", "world"];
a.includes("wor"); // false(部分一致ではない)
a.some(s => s.includes("wor")); // true(文字列の includes を使う)
JavaScriptここが重要です:“配列の”includes は完全一致。部分一致は some+“文字列の”includes で行います。
効率化のコツ
大量データで何度も存在判定をするなら、事前にセット化して O(1) 判定にするのが有効です。
const allowSet = new Set(["png", "jpg", "gif"]);
allowSet.has("png"); // true
JavaScriptここが重要です:繰り返し判定・巨大配列では Set が高速。配列の順序が不要な“集合”用途に向いています。
まとめ
配列内存在チェックは目的別に使い分けます。値の存在だけなら includes、最初/最後の位置が欲しいなら indexOf/lastIndexOf、条件での存在判定は some、要素が欲しいなら find、位置なら findIndex。NaN、型比較、参照同一性(オブジェクト)を理解し、大小や形式の正規化、fromIndex の活用で精度を上げます。大量判定には Set を使って効率化。これらを押さえれば、初心者でも短く安全で意図通りの存在チェックが書けます。
