every
some
every
は、配列の要素全てが特定の条件に合うかどうかをチェックするメソッドです。
const array = [1, 2, 3];
// 配列 array が持つ要素全てが 2 よりも大きいかどうか
const result = array.every((value) => value > 2);
console.log(result); // false
some
は、配列の要素で最低1つが特定の条件に合うかどうかをチェックするメソッドです。
const array = [1, 2, 3];
// 配列 array の中に 2 よりも大きい要素はあるかどうか
const result = array.some((value) => value > 2);
console.log(result); // true
空配列に対して実行した場合の挙動
では、これらのメソッドを、空配列に対して実行した場合はどうなるのでしょうか?
結論から述べると、every
の場合はtrue
、some
の場合はfalse
を返します。
const arrary = [];
const result = arrary.every((value) => value > 2);
console.log(result); // true
const arrary = [];
const result = arrary.some((value) => value > 2);
console.log(result); // false
これが、今回の記事で伝えたいことです!
このような結果になる理由も面白いので、併せて覚えていただけると幸いです。
挙動の解説
every
、some
の挙動は、それぞれ全称量化子と存在量化子という考え方に基づいています。ややこしそうな言葉なのですが、意外と単純です!
全称量化子とは、「集合内のすべての要素がある条件を満たすか」を表すものです。
「集合内のすべての要素が条件と合うかチェックする。」というより、「集合内に条件と矛盾している要素が存在するかどうかチェックする。」と考えると分かりやすいと思います。
空の集合には何も存在しないので、もちろん「条件と矛盾している要素」も存在しません。というわけで全称量化子は常に真となる訳です。
これが、空配列に対してevery
を実行した場合にtrue
を返す理由になります。
存在量化子とは、「集合内に条件を満たす要素が存在するか」を表すものです。
集合の中に、条件を満たした要素の存在がある時点で、真となります。空の集合には何も存在しないので、もちろん「条件を満たした要素」も存在しません。というわけで存在量化子は常に偽となります。
これが、空配列に対してsome
を実行した場合にfalse
を返す理由になります。
まとめると、
- 全称量化子は集合内から条件と矛盾した要素を探す。空の集合には矛盾した要素は存在しないので常に真となる。この考え方に基づき、
every
を空配列に対して実行するとtrue
を返す - 存在量化子は条件を満たした要素の存在を探す。空の集合にはいかなる要素も存在しないので常に偽となる。この考え方に基づき、
some
を空配列に対して実行するとfalse
を返す。
僕が個人的に分かりやすかった例を紹介したいと思います。
空箱を想像してみください...📦
「箱の中に入ったボールが全て赤色ですか?」と聞かれたとします。
その条件と矛盾するボール、つまり赤色以外のボールが無ければ、これは条件を満たしていると言えます。
箱の中身は空です。条件と矛盾するボール、赤色以外のボールはありません!
つまり、「箱の中に入ったボールが全て赤色ですか?」という質問に対しては、「うん!」と答えるのが正しいです。
これが全称量化子な考え方であり、空配列に対してevery
を実行した場合にtrue
を返す理由になります。
では次に、「箱の中に赤色のボールはありますか?」と聞かれたとします。
これは文字通り、箱の中に赤色のボールが存在すれば、「うん!」と言えます。
ですが、箱の中身は空なので、もちろん赤色のボールは見つけられません...
つまり、「箱の中に赤色のボールはありますか?」という質問に対しては、「いいえ!」と答えるのが正しいです。
これが存在量化子な考え方であり、空配列に対してsome
を実行した場合にfalse
を返す理由になります。
他の言語ではどうなる?
今回、JavaScriptのevery
とsome
を挙げましたが、多くの言語にもこれらに相当するメソッド(集合の全ての要素が条件を満たすか、条件を満たす要素が存在するかチェックするメソッド)があります。
全ての言語とは断定できませんが、だいたいのメジャーな言語でも「集合が空の場合、全称量化子に基づくメソッドはtrue
を返し、存在量化子に基づくメソッドはfalse
を返す」というJavaScript同様の挙動になります。
print(all([])) # True
print(any([])) # False
p [].all? { |x| x.even? } # True
p [].any? { |x| x.even? } # False
System.out.println(Arrays.asList().stream().allMatch(x -> (int)x % 2 == 0)); // True
System.out.println(Arrays.asList().stream().anyMatch(x -> (int)x % 2 == 0)); // False
まとめ
- 配列が空の場合、
every
は「全称量化子」の考え方に基づき、true
を返す。 - 配列が空の場合、
some
は「存在量化子」の考え方に基づき、false
を返す。
最後まで読んでいただき、ありがとうございました✨