扩展uniq方法

khe*_*lll 2 ruby monkeypatching unique

这是Ruby 1.8问题:

我们都知道如何使用Array#uniq

[1,2,3,1].uniq #=> [1,2,3]
Run Code Online (Sandbox Code Playgroud)

但是我想知道我们是否可以以一种处理复杂对象的方式对其进行修补。当前行为是这样的:

[{"three"=>"3"}, {"three"=>"4"}, {"three"=>"3"}].uniq 
#=> [{"three"=>"3"}, {"three"=>"4"}, {"three"=>"3"}]
Run Code Online (Sandbox Code Playgroud)

请求的是:

[{"three"=>"3"}, {"three"=>"4"}, {"three"=>"3"}].uniq 
#=> [{"three"=>"3"}, {"three"=>"4"}]
Run Code Online (Sandbox Code Playgroud)

Rya*_*ger 6

要使Array#uniq对任何对象都有效,必须重写两个方法:hash和eql?。

所有对象都有一个哈希方法,该方法计算该对象的哈希值,因此,要使两个对象相等,则它们的哈希值也必须相等。

示例-如果用户的电子邮件地址是唯一的,则该用户是唯一的:

class User
  attr_accessor :name,:email

  def hash
    @email.hash
  end

  def eql?(o)
    @email == o.email
  end
end

>> [User.new('Erin Smith','roo@example.com'),User.new('E. Smith','roo@example.com')].uniq 
=> [#<User:0x1015a97e8 @name="Erin Smith", @email="maynurd@example.com"]
Run Code Online (Sandbox Code Playgroud)