Uguaglianza e hash
Fa parte della sezione Programmazione orientata agli oggetti del percorso Ruby di Coddy. Lezione 37 di 57.
Ruby ha diversi tipi di uguaglianza. == è l’uguaglianza di valore, che definisci per la tua classe. Gli hash e uniq usano invece altri due metodi: eql? e hash. Se definisci solo ==, i punti uguali sono comunque chiavi hash diverse:
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)Risultato:
true
2
nilUn Hash confronta prima i valori hash, numeri calcolati a partire da un oggetto, e poi verifica i candidati con eql?. Definisci entrambi usando gli stessi campi di ==. alias eql? == riutilizza ==, e [x, y].hash combina i campi:
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])Output:
2
firstLa regola è: gli oggetti che sono eql? devono avere lo stesso hash. Due oggetti diversi possono condividere per caso un valore hash, ed è per questo che eql? verifica comunque. Quindi, contare con un Hash funziona sui valori anziché sulle identità:
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}" }Output:
ruby: 3
gem: 1equal? mantiene l'identità e non dovrebbe mai essere ridefinito. I valori integrati seguono già queste regole, ed è per questo che le stringhe e gli array funzionano come chiavi di hash:
a == b # stesso valore (lo definisci tu)
a.eql?(b) # stesso valore per le chiavi Hash e per uniq (alias di ==)
a.hash # un numero; oggetti uguali producono numeri uguali
a.equal?(b) # lo stesso oggetto (non ridefinire mai)Sfida
FacileCompleta la classe Point in modo che i punti con le stesse coordinate siano uguali con ==, eql? e hash, e funzionino come chiavi di Hash. to_s restituisce (1, 2).
Il codice fornito legge i punti da righe nel formato x,y. Stampa il numero di punti distinti con uniq, poi conta le visite per punto in un Hash e le stampa nell’ordine della prima visita come (1, 2): 2, e infine indica se un nuovo Point.new(0, 0) è una chiave.
Il tuo codice va in point.rb. main.rb contiene il codice di input/output fornito e non può essere modificato.
Provalo tu
require_relative 'point'
# Código de entrada/salida proporcionado: mantenlo tal como está
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))}"
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Classi e oggetti
Lavorare con i fileDefinire le classiVariabili d'istanzaMetodi e selfto_s e inspectRipasso - Tessera della biblioteca4Incapsulamento
Metodi privatiMetodi protettiSetter privatiProteggere lo statoRiepilogo - Distributore automatico7Polimorfismo e Duck Typing
PolimorfismoDuck TypingMetodi astratticase e classiRiepilogo - Metodi di pagamento10Pattern di progettazione Parte 2
Delegazione con ForwardablePattern DecoratorPattern BuilderPattern State2Metodi di accesso e self
Metodi di lettura e scritturaSetter personalizzatiself nei metodiIdentità e uguaglianzaRiepilogo - Elenco contatti5Ereditarietà
SottoclassiRidefinizione dei metodiChiamare superis_a? e antenatiRiepilogo - Paghe del personale8Metodi speciali
Uguaglianza e hashMetodi degli operatoriIndicizzazione e appendCollezioni personalizzateRiepilogo - Frazioni11Progetto: Gestione della biblioteca
Libri e iscrittiPrendere in prestito i libriEsercitati da solo: Compilatore Ruby online