Array#any?とArray#all?の論理演算的関係
先に結論
文字列str
と配列array
があるとします。
array.any? { |kw| str[kw] } (または array.any? { |kw| str.slice(kw) })
はarray
に含まれる要素のどれかがstr
に含まれている場合にtrue
を返します。逆に言えば、全く含まれていない場合にのみfalse
を返します。
この否定(!array.any? { |kw| str[kw] }
)、つまりarray
の要素が全く含まれていない場合にのみtrue
を返す文は
array.all? { |kw| !str[kw] }
です。
また、
array.all? { |kw| str[kw] }
はarray
に含まれる要素の全てがstr
に含まれている場合にtrue
を返します。逆に言えば、一つでも含まれていないとfalse
を返します。
この否定(!array.all? { |kw| str[kw] }
)、つまりarray
の要素のどれかがstr
に含まれているが全てではない場合にtrue
を返し、全てが含まれている場合にfalse
を返す文は
array.any? { |kw| !str[kw] }
となります。
具体例
('14 3/9追記)
後で読んでみたときに、イメージが湧きませんでしたw
ので、array
が3要素で、しかもtrue
とfalse
だけだとして中の要素を書き下します。
array.any? == false
array = \ [false, false, false]
array.any? == true
array = \ [false, false, true] || \ [false, true, false] || \ [false, true, true] || \ [false, true, true] || \ [ true, false, false] || \ [ true, false, true] || \ [ true, true, false] || \ [ true, true, true] || \ # array.all? == true
!array.any? == true
array = \ [false, false, false]
つまり array.all? { |a| !a } == true
です。
さらに詳しく言えば、どのi
に対しても a[i] == false
となる状況なので、[true, true, true].all? == true
となるわけです。
!array.any? == false
array = \ [false, false, true] || \ [false, true, false] || \ [false, true, true] || \ [false, true, true] || \ [ true, false, false] || \ [ true, false, true] || \ [ true, true, false] || \ [ true, true, true] || \# !array.all? == false
何に使う?
if
とunless
の入れ替えに使います。
unless 〜
= if !(〜)
なので、unless
で書いたけどif
で書き直してみたい(またはその逆)という際に使えます。
ただし、検証はちゃんとしてくださいね。
解説
まずwikipedia:ド・モルガンの法則から
!(A ∩ B) = !A ∪ !B
!(A ∪ B) = !A ∩ !B
です。
Array#any?
とArray#all?
例えば、文字列str
に対して配列array
の要素のいずれかが含まれるならばtrue
を返すメソッドは
array.any? { |kw| str[kw] }
になります。ブロック内はOR
(||
、∪)で繋がれることになります。
また、str
に対してarray
の要素全てが含まれるならばtrue
を返すメソッドは
array.all? { |kw| str[kw] }
になります。ブロック内はAND
(&&
、∩)で繋がれることになります。
逆を検討
では、array
の要素が全てstr
に含まれないときにtrue
を返すメソッドは、array.any? { |kw| str[kw] }
の否定になるので
!array.any? { |kw| str[kw] }
ですね。当然ですね。
で、これを書き替えると
array.all? { |kw| !str[kw] }
になります。
なぜならば、array = [a1, a2, .. an]
としたときに、
!array.any? { |kw| str[kw] }
は
!(str[a1] OR str[a2] OR .. OR str[an])
となりますが、ド・モルガンの法則を前から一つずつ当てはめていくと最終的に
!str[a1] AND !str[a2] AND .. AND !str[an]
と変形されます。これはArray#all?
と同じです。
ということで
array.all? { |kw| !str[kw] }
になります。
Array#all?
の否定も同様です。