概要
cover?
とinclude?
は,ともに範囲内に値が含まれるかを判断するメソッドです。
両者の挙動の違いについて調べることがあったので,メモとしてまとめます。
結論
include?
は原則として離散値を扱い、cover?
は連続値を扱う。
ただし,数値に関してはinclude?
も例外的に連続値を扱うので,cover?
と同じ挙動になる。
※離散値は,連続していない状態の値,連続値は切れ目がなく連続している値のこと。
数値を扱う場合
(1..5).cover?(3) # => true
(1..5).include?(3) # => true
挙動は同じ。
数値以外を扱う場合
("b".."d").cover?("ba") # => true
("b".."d").include?("ba") # => false
cover?
は<=>
メソッドによる演算により"ba"
が"b"
から"d"
の範囲内にあるかを確認しています。
※すみません,ここは確証が持てないのですが,2つの文字列をASCII コード順で比較しており
"ba" >= "b" # => true
"ba" <= "d" # => true
であるためtrue
になると解釈しました。
(参考:https://docs.ruby-lang.org/ja/latest/method/String/i/=3c=3d=3e.html )
一方,include?
は**「"ba"
が範囲内に完全に一致する値が含まれるかどうか」**を確認しています。
数値以外については,離散値を扱うので,"b".."d"
は"b", "c", "d"
となり,この中には"ba"
に一致するものがありません。
なのでfalse
になります。
以下の例のほうがさらに分かりやすいかも?
("a".."z").cover?("yellow") # => true
("a".."z").include?("yellow") # => false
("yellaa".."yellzz").include?("yellow") #=> true
("aaaaaa".."zzzzzz").include?("yellow") #=> true
※ちなみに↑こちらの一番下のコードは実行すると50秒くらい掛かりました。
地道に一致する値を探しているのがよく分かります。
(参考:https://stackoverflow.com/questions/21608935/what-is-the-difference-between-rangeinclude-and-rangecover/21609473 )
##【補足】include?の他の使い方
include?
については,以下のように配列や文字列に対して使うものもあります。
配列
https://docs.ruby-lang.org/ja/latest/method/Array/i/include=3f.html
文字列
https://docs.ruby-lang.org/ja/latest/method/String/i/include=3f.html
ちなみに,現役エンジニアの方は**「include?
は離散的なものに使用するイメージがある(とびとびのもの,Arrayに使うことが多く,Rangeには普通使わない)」**とおっしゃっていました。
【参考】ちなみにbetween?は・・・
between?
は比較演算子 <=>
をもとに値が範囲内にあるかを判断します。
内容を見る限り,<=>
をもとに範囲内にあるかを判断している点から,書き方は違えどcover?
と同じ挙動をすると思っていますが,確証が持てません^^;
# 以下は同じ意味?
3.between?(1, 5) # => true
(1..5).cover?(3) # => true
# 以下は同じ意味?
('a'..'z').cover?('yellow') # => true
('yellow').between?('a','z') # => true
(上記以外にも色々な値を検証したところ,同じ結果は返ってきましたが・・)
もしご存知の方がいらっしゃったら,教えていただけたらとても嬉しいです。
終わりに
以上,調べた内容をまとめました。
もし間違いがありましたら,ご指摘いただけますと幸いです☺️