Gleichheit und Hash
Teil des Abschnitts Objektorientierte Programmierung der Ruby-Journey von Coddy. Lektion 37 von 57.
Ruby hat mehrere Arten von Gleichheit. == ist Wertgleichheit, die du für deine Klasse definierst. Hashes und uniq verwenden stattdessen zwei andere Methoden: eql? und hash. Wenn nur == definiert ist, sind gleiche Punkte weiterhin unterschiedliche Hash-Schlüssel:
class Point
attr_reader :x, :y
def initialize(x, y)
@x = x
@y = y
end
def ==(other)
other.is_a?(Point) && x == other.x && y == other.y
end
end
a = Point.new(1, 2)
b = Point.new(1, 2)
puts a == b
puts [a, b].uniq.size
puts({ a => "first" }[b].inspect)Ausgabe:
true
2
nilEin Hash vergleicht zuerst hash-Werte, also aus einem Objekt berechnete Zahlen, und prüft dann die Kandidaten mit eql?. Definiere beide anhand derselben Felder wie ==. alias eql? == verwendet == wieder, und [x, y].hash kombiniert die Felder:
class Point
attr_reader :x, :y
def initialize(x, y)
@x = x
@y = y
end
def ==(other)
other.is_a?(Point) && x == other.x && y == other.y
end
alias eql? ==
def hash
[x, y].hash
end
end
a = Point.new(1, 2)
b = Point.new(1, 2)
puts [a, b, Point.new(3, 4)].uniq.size
puts({ a => "first" }[b])Ausgabe:
2
firstDie Regel lautet: Objekte, die eql? sind, müssen denselben hash haben. Zwei verschiedene Objekte können zufällig denselben Hash-Wert haben, weshalb eql? weiterhin prüft. Das Zählen mit einem Hash funktioniert dann anhand von Werten statt Identitäten:
class Word
attr_reader :text
def initialize(text)
@text = text.downcase
end
def ==(other)
other.is_a?(Word) && text == other.text
end
alias eql? ==
def hash
text.hash
end
end
counts = Hash.new(0)
%w[Ruby ruby RUBY gem].each { |t| counts[Word.new(t)] += 1 }
counts.each { |word, n| puts "#{word.text}: #{n}" }Ausgabe:
ruby: 3
gem: 1equal? bleibt die Identität und sollte niemals neu definiert werden. Integrierte Werte folgen diesen Regeln bereits, weshalb Strings und Arrays als Hash-Schlüssel funktionieren:
a == b # gleicher Wert (du definierst ihn)
a.eql?(b) # gleicher Wert für Hash-Schlüssel und uniq (Alias von ==)
a.hash # eine Zahl; gleiche Objekte ergeben gleiche Zahlen
a.equal?(b) # dasselbe Objekt (niemals neu definieren)Aufgabe
EinfachVervollständige die Klasse Point, sodass Punkte mit denselben Koordinaten mit ==, eql? und hash gleich sind und als Hash-Schlüssel funktionieren. to_s gibt (1, 2) zurück.
Der bereitgestellte Code liest Punkte als Zeilen im Format x,y ein. Er gibt mit uniq die Anzahl der unterschiedlichen Punkte aus, zählt dann die Besuche pro Punkt in einem Hash und gibt sie in der Reihenfolge des ersten Besuchs als (1, 2): 2 aus und schließlich, ob ein neuer Point.new(0, 0) ein Schlüssel ist.
Dein Code gehört in point.rb. main.rb enthält den bereitgestellten Eingabe-/Ausgabecode und darf nicht bearbeitet werden.
Probier es selbst
require_relative 'point'
# Gelieferter Ein-/Ausgabe-Code: belasse ihn wie er ist
input = []
while (line = gets)
input << line.chomp
end
points = input.map { |line| Point.new(*line.split(",").map(&:to_i)) }
puts "distinct: #{points.uniq.size}"
visits = Hash.new(0)
points.each { |pt| visits[pt] += 1 }
visits.each { |pt, n| puts "#{pt}: #{n}" }
puts "origin visited: #{visits.key?(Point.new(0, 0))}"
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Klassen und Objekte
Arbeiten mit DateienKlassen definierenInstanzvariablenMethoden und selfto_s und inspectRückblick – Bibliotheksausweis4Kapselung
Private MethodenGeschützte MethodenPrivate SetterZustand schützenRückblick – Verkaufsautomat7Polymorphismus und Duck Typing
PolymorphismusDuck TypingAbstrakte MethodenFälle und KlassenRückblick – Zahlungsmethoden2Getter und Setter sowie self
Leser und SchreiberBenutzerdefinierte Setterself in MethodenIdentität und GleichheitWiederholung – Kontaktliste5Vererbung
UnterklassenMethoden überschreibensuper aufrufenis_a? und VorfahrenRückblick – Gehaltsabrechnung des Personals8Spezielle Methoden
Gleichheit und HashOperator-MethodenIndexieren und AnhängenBenutzerdefinierte CollectionsRückblick – Brüche11Projekt: Bibliotheksverwaltung
Bücher und MitgliederBücher ausleihenÜbe selbstständig: Online-Ruby-Compiler