2014-02-06 3 views
27

Bearbeiten Behoben, dass toro2k's Kommentar folgt.Was ist der Unterschied zwischen `Range # include?` Und `Range # cover?`?

Range#include? und Range#cover? scheinen anders zu sein als in den Quellcode 1, 2 gesehen, und sie unterscheiden sich in der Effizienz.

t = Time.now 
500000.times do 
    ("a".."z").include?("g") 
end 
puts Time.now - t # => 0.504382493 

t = Time.now 
500000.times do 
    ("a".."z").cover?("g") 
end 
puts Time.now - t # => 0.454867868 

auf den Quellcode Sehen, Range#include? scheint als Range#cover? komplexer zu sein. Warum kann Range#include? nicht einfach ein Alias ​​von Range#cover? sein Was ist der Unterschied?

+0

Ich war auch davon verwirrt. Siehe mein [hier antworten] (http://stackoverflow.com/questions/21507117/select-arrays-between-date-ranges-with-ruby/21507252#21507252). –

Antwort

34

Die beiden Methoden wurden entwickelt, um absichtlich zwei leicht unterschiedliche Dinge zu tun. Intern werden sie auch sehr unterschiedlich umgesetzt. Sie können in den documentation an den Quellen einen Blick und sehen, dass .include? viel tut mehr als .cover?

Die .cover? Methode zum Comparable Modul verbunden ist, und prüft, ob ein Element zwischen den Endpunkten in einem sortierten passen würde Liste. Es wird True zurückgegeben, auch wenn das Element nicht in dem Satz enthalten ist, der durch die Range impliziert wird.

Die .include?-Methode bezieht sich auf das Modul Enumerable und überprüft, ob ein Element tatsächlich im vollständigen Satz enthalten ist, der durch die Range impliziert wird. Es gibt einige Feinheiten mit Zahlen - Ganzzahlbereiche werden als alle impliziten Float Werte gezählt (ich weiß nicht warum).

könnte Diese Beispiele helfen:

('a'..'z').cover?('yellow') 
# => true 

('a'..'z').include?('yellow') 
# => false 

('yellaa'..'yellzz').include?('yellow') 
=> true 

Wenn Sie darüber hinaus

('aaaaaa'..'zzzzzz').include?('yellow') 

versuchen sollten Sie bemerken, dass es eine viel längere Zeit in Anspruch nimmt als

('aaaaaa'..'zzzzzz').cover?('yellow') 
+3

Ich sehe. Jetzt sieht es für mich so aus, dass "Range # include?" Sehr geheimnisvoll ist. – sawa

6

Der Hauptunterschied ist, dass include w prüft Das Objekt ist eines der Bereichselemente, und die Abdeckung gibt zurück, ob sich das Objekt zwischen Kantenelementen befindet. Sie können sehen, dass:

('a'..'z').include?('cc')  #=> false 
('a'..'z').cover?('cc')  #=> true 
0
date_range = {:start_date => (DateTime.now + 1.days).to_date, :end_date => (DateTime.now + 10.days).to_date}     
date_range_to_check_for_coverage = {:start_date => (DateTime.now + 5.days).to_date, :end_date => (DateTime.now + 7.days).to_date}     

(date_range[:start_date]..date_range[:end_date]).include?((DateTime.now + 5.days).to_date)     
#true   
(date_range[:start_date]..date_range[:end_date]).cover?((DateTime.now + 5.days).to_date)     
#true   
(date_range[:start_date]..date_range[:end_date]).include?(date_range_to_check_for_coverage[:start_date]..date_range_to_check_for_coverage[:end_date])     
#true   
(date_range[:start_date]..date_range[:end_date]).cover?(date_range_to_check_for_coverage[:start_date]..date_range_to_check_for_coverage[:end_date])     
#false   

Sollte nicht die letzte Zeile true zurück?

Der Grund, den ich frage, ist rubocop kennzeichnet einen Konflikt, wenn ich include verwende? anstelle von Abdeckung ?. Und klar, meine Logik (um zu prüfen, ob der Bereich in einem anderen Bereich enthalten ist) funktioniert nicht mit Cover ?.

Verwandte Themen