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 birkaç eşitlik 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 başka yöntem kullanır: eql? ve hash. Yalnızca == tanımlandığında, eşit noktalar yine de 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 hash değerlerini, yani bir nesneden hesaplanan sayıları karşılaştırır, ardından eql? ile adayları denetler. Her ikisini de == ile aynı alanları kullanarak 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 şans eseri aynı hash değerini paylaşabilir; bu yüzden eql? yine de kontrol eder. Böylece Hash ile sayım, kimlikler yerine değerler üzerinden yapılı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? nesne kimliğini belirtir ve asla yeniden tanımlanmamalıdır. Yerleşik değerler bu kurallara zaten uyar; bu nedenle dizeler ve diziler Hash anahtarı olarak kullanılabilir:
a == b # aynı değer (bunu siz tanımlarsınız)
a.eql?(b) # Hash anahtarları ve uniq için aynı değer (== için takma ad)
a.hash # bir sayı; eşit nesneler eşit sayılar üretir
a.equal?(b) # aynı nesne (asla yeniden tanımlamayın)Görev
KolayPoint sınıfını, koordinatları aynı olan noktalar ==, eql? ve hash ile eşit olacak ve Hash anahtarı olarak kullanılabilecek şekilde tamamla. to_s, (1, 2) döndürür.
Verilen 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 her noktanın ziyaret sayısını hesaplar 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 bir anahtar olup olmadığını yazdırır.
Kodunu point.rb dosyasına yaz. main.rb, verilen giriş/çıkış 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