首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >扩展uniq法

扩展uniq法
EN

Stack Overflow用户
提问于 2009-10-13 04:19:00
回答 6查看 860关注 0票数 2

这是Ruby1.8问题:

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

代码语言:javascript
复制
[1,2,3,1].uniq #=> [1,2,3]

但是,我想知道我们是否可以用猴子补丁来处理复杂的对象。当前的行为如下:

代码语言:javascript
复制
[{"three"=>"3"}, {"three"=>"4"}, {"three"=>"3"}].uniq 
#=> [{"three"=>"3"}, {"three"=>"4"}, {"three"=>"3"}]

所要求的是:

代码语言:javascript
复制
[{"three"=>"3"}, {"three"=>"4"}, {"three"=>"3"}].uniq 
#=> [{"three"=>"3"}, {"three"=>"4"}]
EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2009-10-13 04:40:51

它已经在1.8.7中对我起作用了。

代码语言:javascript
复制
1:~$ ruby -v
ruby 1.8.7 (2008-08-11 patchlevel 72) [i486-linux]
1:~$ irb -v
irb 0.9.5(05/04/13)
1:~$ irb
>> [{"three"=>"3"}, {"three"=>"4"}, {"three"=>"3"}].uniq 
=> [{"three"=>"3"}, {"three"=>"4"}]
票数 4
EN

Stack Overflow用户

发布于 2010-11-12 21:24:04

要使Array#uniq为任何对象工作,您必须重写两个方法:哈希和eql?

所有对象都有一个哈希方法,该方法计算该对象的哈希值,因此,如果两个对象的值相等,则散列时的值也必须相等。

示例--当用户的电子邮件地址是唯一的时,用户是唯一的:

代码语言:javascript
复制
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"]
票数 6
EN

Stack Overflow用户

发布于 2009-10-13 15:51:38

问题是Hash#hashHash#eql?都给出了Ruby1.8.6中的假结果。这是我愿意执行的非常罕见的猴子补丁之一,因为这个bug严重破坏了许多代码,特别是回忆录功能。只是要小心猴子的补丁,你不能覆盖没有破坏的行为。

所以:

代码语言:javascript
复制
class Hash
  if {}.hash != {}.hash
    def hash
      # code goes here
    end
  end
  if !{}.eql?({})
    def eql?(other)
      # code goes here
    end
  end
end

但是,如果您正在执行控制部署环境的操作,那么如果应用程序是从1.8.6开始的,就会引发一个错误。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1558166

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档