何をしたいユーティリティか:「OR 条件検索」
「OR 条件検索」は、配列の中から「いくつかの条件のうち、どれか1つでも満たしていればOK」という要素を探す処理です。
論理式でいう「A または B または C」の“OR(または)”です。
業務だと、例えばこういう場面で使います。
エラーログか警告ログのどちらかを全部取りたい。
「admin か editor」のユーザーを抽出したい。
「在庫ゼロか、価格が高すぎる」商品を見つけたい。
ポイントは、「全部満たす必要がある AND 条件」とは違い、どれか1つでも条件を満たせばヒットするということです。
基本形:OR 条件で1件だけ見つける findByAny
「どれか1つでも条件を満たす最初の1件」を返す
まずは、「複数条件のうち、どれか1つでも満たす最初の1件」を探すユーティリティです。
function findByAny(array, predicates) {
if (!Array.isArray(array)) {
return undefined;
}
if (!Array.isArray(predicates) || predicates.length === 0) {
return undefined;
}
return array.find((item, index) =>
predicates.some((p) => typeof p === "function" && p(item, index))
);
}
JavaScriptここでの重要ポイントをかみ砕きます。
predicates は「条件関数の配列」です(OR でつなぎたい条件をここに詰める)。some は「1つでも true があれば true」を返す関数です。
つまり、「複数条件のうち、どれか1つでも true なら、その要素はヒット」とみなします。array.find(...) なので、「最初にヒットした1件」だけ返し、なければ undefined を返します。
これが、OR 条件検索の基本形です。
例題:エラーか警告のログを1件だけ探す
const logs = [
{ level: "info", message: "OK" },
{ level: "warning", message: "Slow" },
{ level: "error", message: "Failed" },
];
const isError = (log) => log.level === "error";
const isWarning = (log) => log.level === "warning";
const firstImportant = findByAny(logs, [isError, isWarning]);
console.log(firstImportant);
// { level: "warning", message: "Slow" }
JavaScript「error または warning」のうち、最初に出てきたログ(warning)が返ってきます。
OR 条件で「全部ほしい」パターン findAllByAny
「どれか1つでも条件を満たす要素を全部」取りたい
次は、「最初の1件」ではなく、「OR 条件を満たすものを全部ほしい」パターンです。
function findAllByAny(array, predicates) {
if (!Array.isArray(array)) {
return [];
}
if (!Array.isArray(predicates) || predicates.length === 0) {
return [];
}
return array.filter((item, index) =>
predicates.some((p) => typeof p === "function" && p(item, index))
);
}
JavaScriptfind が「最初の1件」なのに対して、filter は「条件を満たすもの全部」です。
中身のロジックは findByAny と同じで、「some で OR 条件をまとめている」のがポイントです。
例題:エラーか警告のログを全部取得
const logs = [
{ level: "info", message: "OK" },
{ level: "warning", message: "Slow" },
{ level: "error", message: "Failed" },
{ level: "debug", message: "Detail" },
];
const isError = (log) => log.level === "error";
const isWarning = (log) => log.level === "warning";
const importantLogs = findAllByAny(logs, [isError, isWarning]);
console.log(importantLogs);
/*
[
{ level: "warning", message: "Slow" },
{ level: "error", message: "Failed" },
]
*/
JavaScript「error または warning」のログだけが抽出されています。
AND 条件との違いをはっきり意識する
every(AND)と some(OR)の違い
複数条件検索には、AND と OR の2種類があります。
AND 条件(かつ)
すべての条件を満たす必要がある。predicates.every(...) を使う。
OR 条件(または)
どれか1つでも条件を満たせばよい。predicates.some(...) を使う。
例えばユーザー検索で、
const isActive = (u) => u.active;
const isAdmin = (u) => u.role === "admin";
JavaScriptとしたとき、
「active かつ admin」 → AND 条件 → every([isActive, isAdmin])
「active または admin」 → OR 条件 → some([isActive, isAdmin])
となります。
ここを取り違えると、「本当はどれか1つでよかったのに、全部満たさないとヒットしない」など、業務上のバグにつながります。
ユーティリティ名で findByAll(AND)と findByAny(OR)を分けておくと、意図が読みやすくなります。
OR 条件検索を業務ロジックに組み込む例
「admin か editor のユーザーを全部取得」
const users = [
{ id: 1, role: "user" },
{ id: 2, role: "admin" },
{ id: 3, role: "editor" },
{ id: 4, role: "guest" },
];
const isAdmin = (u) => u.role === "admin";
const isEditor = (u) => u.role === "editor";
const privileged = findAllByAny(users, [isAdmin, isEditor]);
console.log(privileged);
/*
[
{ id: 2, role: "admin" },
{ id: 3, role: "editor" },
]
*/
JavaScript「admin または editor」という OR 条件を、関数の組み合わせで表現できています。
「在庫ゼロか価格が高すぎる商品をチェック」
const items = [
{ id: 1, stock: 0, price: 500 },
{ id: 2, stock: 10, price: 1500 },
{ id: 3, stock: 5, price: 4000 },
];
const isOutOfStock = (item) => item.stock === 0;
const isTooExpensive = (item) => item.price > 3000;
const problematic = findAllByAny(items, [isOutOfStock, isTooExpensive]);
console.log(problematic);
/*
[
{ id: 1, stock: 0, price: 500 },
{ id: 3, stock: 5, price: 4000 },
]
*/
JavaScript「在庫ゼロまたは高すぎる」という OR 条件で、問題のある商品だけを抽出できます。
手を動かして OR 条件検索の感覚をつかむ
コンソールで、次のコードを実際に打ってみてください。
function findByAny(array, predicates) {
if (!Array.isArray(array)) return undefined;
if (!Array.isArray(predicates) || predicates.length === 0) return undefined;
return array.find((item, index) =>
predicates.some((p) => typeof p === "function" && p(item, index))
);
}
function findAllByAny(array, predicates) {
if (!Array.isArray(array)) return [];
if (!Array.isArray(predicates) || predicates.length === 0) return [];
return array.filter((item, index) =>
predicates.some((p) => typeof p === "function" && p(item, index))
);
}
const logs = [
{ level: "info", message: "OK" },
{ level: "warning", message: "Slow" },
{ level: "error", message: "Failed" },
];
const isError = (log) => log.level === "error";
const isWarning = (log) => log.level === "warning";
console.log(findByAny(logs, [isError, isWarning]));
console.log(findAllByAny(logs, [isError, isWarning]));
JavaScript「どのログがヒットするか」「条件を1つ増やしたらどう変わるか」を、自分の手で試してみてください。
まとめ:OR 条件検索ユーティリティで“複雑な検索条件”を整理する
OR 条件検索は、「どれか1つでも条件を満たせばOK」という柔軟な絞り込みを実現するための道具です。
業務コードでは、AND と OR が混ざった複雑な条件がよく出てきますが、
条件を小さな関数として分解する。
AND は findByAll / OR は findByAny に任せる。
検索ロジックを「配列ユーティリティ」として外出しする。
こうしておくと、検索条件の変更・追加・テストがとても楽になります。
プロジェクトに
export function findByAny(...) { ... }
export function findAllByAny(...) { ... }
JavaScriptのような関数を置き、「“A または B”で探したくなったら必ずこれを通す」と決めておくと、
検索ロジックが整理されて、コードの“業務レベル感”が一段上がります。
