Eşitlik ve hash
Coddy'nin Ruby Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 37 / 57.
Ruby’de eşitliğin birkaç türü vardır. ==, sınıfınız için tanımladığınız değer eşitliğidir. Hash’ler ve uniq bunun yerine iki farklı yöntem kullanır: eql? ve hash. Yalnızca == tanımlandığında, eşit noktalar hâlâ farklı hash anahtarlarıdır:
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)Çıktı:
true
2
nilBir Hash önce nesneden hesaplanan sayılar olan hash değerlerini karşılaştırır, ardından adayları eql? ile denetler. Her ikisini de == ile aynı alanlardan tanımlayın. alias eql? ==, == yöntemini yeniden kullanır ve [x, y].hash alanları birleştirir:
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])Çıktı:
2
firstKural şudur: eql? olan nesneler aynı hash değerine sahip olmalıdır. İki farklı nesne tesadüfen aynı hash değerini paylaşabilir; bu nedenle eql? kontrol yapmaya devam eder. Ardından Hash ile sayma, kimlikler yerine değerler üzerinden çalışır:
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}" }Çıktı:
ruby: 3
gem: 1equal? özdeşliği korur ve asla yeniden tanımlanmamalıdır. Yerleşik değerler zaten bu kurallara uyar; dizelerin ve dizilerin karma tablolarında anahtar olarak çalışmasının nedeni budur:
a == b # aynı değer (siz tanımlarsınız)
a.eql?(b) # Hash anahtarları ve uniq için aynı değer (== takma adı)
a.hash # bir sayı; eşit nesneler eşit sayılar verir
a.equal?(b) # aynı nesne (asla yeniden tanımlamayın)Görev
KolayPoint sınıfını, aynı koordinatlara sahip noktalar ==, eql? ve hash ile eşit olacak ve Hash anahtarları olarak çalışacak şekilde tamamla. to_s, (1, 2) değerini döndürür.
Sağlanan kod, noktaları x,y satırları olarak okur. uniq ile farklı noktaların sayısını yazdırır, ardından bir Hash içinde nokta başına ziyaretleri sayar ve bunları ilk ziyaret sırasına göre (1, 2): 2 olarak yazdırır; son olarak da yeni bir Point.new(0, 0) nesnesinin anahtar olup olmadığını belirtir.
Kodun point.rb dosyasına yazılmalıdır. main.rb sağlanan girdi/çıktı kodunu içerir ve düzenlenemez.
Kendin dene
require_relative 'point'
# Sağlanan girdi/çıktı kodu: olduğu gibi bırakın
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))}"
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama bölümündeki tüm dersler
1Sınıflar ve Nesneler
Dosyalarla ÇalışmaSınıf TanımlamaÖrnek DeğişkenleriMetotlar ve selfto_s ve inspectÖzet - Kütüphane Kartı7Çok Biçimlilik ve Ördek Tiplemesi
Çok BiçimlilikÖrdek TiplemesiSoyut Metotlarcase ve SınıflarTekrar - Ödeme Yöntemleri2Erişimciler ve self
Okuyucular ve YazıcılarÖzel Setter'larMetotlarda selfKimlik ve EşitlikTekrar - Kişi Listesi5Kalıtım
Alt sınıflarMetotları geçersiz kılmasuper çağrısıis_a? ve üst sınıflarTekrar - Personel Maaşları8Özel Metotlar
Eşitlik ve hashOperatör Metotlarıİndeksleme ve EklemeÖzel KoleksiyonlarTekrar - Kesirler11Proje: Kütüphane Yönetimi
Kitaplar ve ÜyelerKitap Ödünç Alma3Sınıf Metotları ve Değişkenleri
Sınıf MetotlarıSınıf Örnek DeğişkenleriSabitlerFabrika MetotlarıTekrar - Kupon KodlarıKendi başına pratik yap: Online Ruby derleyicisi