「大文字小文字無視検索」とは何をしてくれるのか
まずゴールのイメージからいきます。
次の3つの文字列を見てください。
"Apple"
"apple"
"APPLE"
人間からすると「全部 Apple でしょ」ですが、コンピュータ的には全部別物です。
そのまま includes("apple") すると、 "Apple" や "APPLE" はヒットしません。
でも業務では、「大文字か小文字かなんてどうでもいいから、とにかく“apple”を含むものを探したい」という場面が圧倒的に多いです。
この「大文字・小文字の違いを無視して検索する」ための小さな道具が、大文字小文字無視検索ユーティリティです。
なぜ毎回その場で書かず、ユーティリティにするのか
大文字小文字を無視したいとき、よくやるのはこういう書き方です。
text.toLowerCase().includes(keyword.toLowerCase());
JavaScript一見これで十分に見えますが、実務では次のような問題が出てきます。
同じようなコードが画面ごとにコピペされる。
どこか一箇所だけ toUpperCase を使っていたりして挙動が微妙に違う。
null や undefined が来たときに片方だけ落ちる。
こういう「じわじわ効いてくる不具合」を避けるために、
“検索用の正規化”を一箇所にまとめたユーティリティを用意しておく価値があります。
基本の考え方:両方を同じルールで正規化してから検索する
大文字小文字無視検索の本質は、とてもシンプルです。
検索対象の文字列を、あるルールで正規化する。
検索キーワードも、同じルールで正規化する。
正規化後の文字列同士で、includes や indexOf などを使って検索する。
ここでいう「正規化」の最低限は、小文字にそろえることです。
つまり、「全部小文字にしてから検索する」ということです。
実装例:大文字小文字無視の部分一致検索
まずは一番基本のユーティリティ
部分一致(どこかに含まれていればOK)のケースからいきます。
function includesIgnoreCase(text, keyword) {
if (text == null || keyword == null) return false;
const t = String(text).toLowerCase();
const k = String(keyword).toLowerCase();
if (k === "") return true;
return t.includes(k);
}
JavaScript重要なポイントを噛み砕きます。
text や keyword が null / undefined でも落ちないように、最初にチェックしていること。String(...) で一度文字列に変換してから toLowerCase() していること。
キーワードが空文字のときは true を返していること(検索 UI 的に自然な挙動)。
最後は普通の includes で判定しているだけなこと。
使い方はこんな感じです。
includesIgnoreCase("Apple Pie", "apple"); // true
includesIgnoreCase("APPLE PIE", "apple"); // true
includesIgnoreCase("apple pie", "APPLE"); // true
includesIgnoreCase("Banana Cake", "apple"); // false
JavaScript「大文字小文字を無視して検索したい」という要件は、ほぼこれで満たせます。
前方一致・後方一致にもそのまま応用できる
大文字小文字無視検索の考え方は、部分一致だけの話ではありません。
前方一致(先頭が一致しているか)、後方一致(末尾が一致しているか)にも、そのまま使えます。
例えば前方一致ならこうです。
function startsWithIgnoreCase(text, prefix) {
if (text == null || prefix == null) return false;
const t = String(text).toLowerCase();
const p = String(prefix).toLowerCase();
if (p === "") return true;
return t.startsWith(p);
}
JavaScript後方一致ならこうです。
function endsWithIgnoreCase(text, suffix) {
if (text == null || suffix == null) return false;
const t = String(text).toLowerCase();
const s = String(suffix).toLowerCase();
if (s === "") return true;
return t.endsWith(s);
}
JavaScriptどちらも「両方を小文字にそろえてから、標準メソッドで判定する」という同じパターンです。
つまり、「大文字小文字無視」は“前処理のルール”であって、“検索の種類”とは独立しているということです。
業務での具体的な使いどころ
一覧画面の検索・絞り込み
ユーザー一覧や商品一覧の検索ボックスでは、
ユーザーが大文字で打つか小文字で打つかなんて、いちいち気にしてほしくありません。
const users = [
{ name: "Taro Yamada" },
{ name: "Hanako Sato" },
{ name: "taro Suzuki" },
];
function filterUsersByName(users, keyword) {
return users.filter((user) =>
includesIgnoreCase(user.name, keyword)
);
}
filterUsersByName(users, "taro");
// Taro Yamada / taro Suzuki の2件がヒット
JavaScriptここで includesIgnoreCase を使っておけば、
「Taro」「taro」「TARO」どれで検索しても同じ結果になります。
メールアドレスやユーザーIDの検索
メールアドレスやユーザーIDは、
「大文字小文字を区別しない」と決めることが多いです。
const users = [
{ email: "taro@example.com" },
{ email: "HANAKO@example.com" },
];
function findByEmail(users, email) {
return users.find((user) =>
includesIgnoreCase(user.email, email)
);
}
findByEmail(users, "TARO@example.com"); // taro@example.com が見つかる
findByEmail(users, "hanako@EXAMPLE.COM"); // HANAKO@example.com が見つかる
JavaScript本当は「保存時に小文字に正規化しておく」のがベストですが、
既存データが混在している場合でも、
大文字小文字無視検索ユーティリティがあると、かなり救われます。
設計として一番大事なポイント
「検索用の正規化」を一箇所にまとめる
ここが本当に重要です。
大文字小文字無視検索を、毎回こう書いてしまうとします。
text.toLowerCase().includes(keyword.toLowerCase());
JavaScript一見同じことをしているようで、現場ではこうなりがちです。
どこか一箇所だけ toUpperCase を使っている。
どこか一箇所だけ trim() を足している。
どこか一箇所だけ null チェックを忘れている。
結果として、「画面Aではヒットするのに、画面Bではヒットしない」という
ユーザーから見て意味不明な差が生まれます。
それを防ぐために、
「大文字小文字無視検索は includesIgnoreCase を必ず使う」
「前方一致なら startsWithIgnoreCase、後方一致なら endsWithIgnoreCase を使う」
というルールにしてしまうのが、設計としてとても強いです。
「何を無視して、何を区別するか」を明文化する
大文字小文字だけでなく、
全角・半角、前後のスペース、記号の扱いなど、
「どこまでを同じとみなすか」はプロダクトごとに違います。
例えば、もう一歩踏み込んで「全角英数字も半角に寄せる」なら、toLowerCase() の前に全角→半角の処理を入れて、
それを normalizeForSearch のような関数にまとめておくとよいです。
大事なのは、
「この検索は、大文字小文字だけ無視する」
「この検索は、大文字小文字+全角半角も無視する」
といった“ルール”を、関数名やコメントでちゃんと表現しておくことです。
ちょっとだけ手を動かしてみる
ブラウザのコンソールで、次のあたりを試してみてください。
"Apple Pie".includes("apple");
"Apple Pie".toLowerCase().includes("apple");
includesIgnoreCase("Apple Pie", "apple");
includesIgnoreCase("APPLE PIE", "Apple");
includesIgnoreCase(null, "apple");
includesIgnoreCase("Banana Cake", "");
JavaScriptどこからが true で、どこからが false になるかを体で感じてみてください。
特に「null でも落ちない」「空文字キーワードは true」という挙動が、
実務でどれだけ効いてくるかをイメージできると、一気に設計の目線が上がります。
そのうえで、自分のプロジェクトに
export function includesIgnoreCase(text, keyword) { ... }
JavaScriptを一つ置いて、
「大文字小文字を無視したい検索は、必ずここを通す」
というルールにしてみてください。
その瞬間、あなたの検索処理は
「その場しのぎの toLowerCase の寄せ集め」から
「意図を持って設計された検索ユーティリティ」に、一段レベルアップします。
