代码之家  ›  专栏  ›  技术社区  ›  stephenr

Ruby Set类:集合的相等性

  •  4
  • stephenr  · 技术社区  · 14 年前

    根据Ruby Set类的文档,如果两个集合相等,“==返回true。每对元素的相等性是根据Object#eql?定义的?。

    这一点的本质可以通过使用日期对象来说明,其中包含不同日期对象但具有相同日期的集合比较为相等:

    require 'set'
    d1 = Date.today              # => Thu, 30 Sep 2010
    puts d1.object_id            # => 2211539680
    d2 = Date.today + 1          # => Fri, 01 Oct 2010
    puts d2.object_id            # => 2211522320
    set1 = Set.new([d1, d2])
    
    d11 = Date.today             # => Thu, 30 Sep 2010
    puts d11.object_id           # => 2211489080
    d12 = Date.today + 1         # => Fri, 01 Oct 2010
    puts d12.object_id           # => 2211469380
    set2 = Set.new([d12, d11])
    
    set1 == set2                 # => true
    

    但是使用我自己的对象,在那里我编写了eql?方法只比较某些属性,我无法让它工作。

    class IpDet
    
        attr_reader :ip, :gateway
    
        def initialize(ip, gateway, netmask, reverse)
            @ip = ip
            @gateway = gateway
            @netmask = netmask
            @reverse = reverse
        end
    
        def eql?(other)
            if @ip = other.ip && @gateway == other.gateway
                return true
            else
                return false
            end
        end
    end
    
    
    
    ipdet1 = IpDet.new(123456, 123457, 123458, 'example.com')
    ipdet2 = IpDet.new(234567, 2345699, 123458, 'nil')
    
    ipdet11 = IpDet.new(123456, 123457, 777777, 'other_domain.com')
    ipdet12 = IpDet.new(234567, 2345699, 777777, 'example.com')
    
    puts "ipdet1 is equal to ipdet11: #{ipdet1.eql?(ipdet11)}"
    puts "ipdet2 is equal to ipdet12: #{ipdet2.eql?(ipdet12)}"
    
    
    set1 = Set.new([ipdet1, ipdet2])
    set2 = Set.new([ipdet11, ipdet12])
    
    puts "set 1 is equal to set2: #{set1 == set2}"
    

    我从上面得到的结果是:

    ipdet1 is equal to ipdet11: true
    ipdet2 is equal to ipdet12: true
    set 1 is equal to set2: false
    

    1 回复  |  直到 14 年前
        1
  •  14
  •   sepp2k    14 年前

    当你覆盖 eql? hash 如果 o1.eql?(o2) o1.hash == o2.hash 这也是事实。

    例如,哈希方法可以如下所示:

    def hash
      [@ip, @gateway].hash
    end
    

    你也有一个拼写错误在你的 eql? 方法: @ip = other.ip 应该是 @ip == other.ip .

    if condition then true else false end 相当于 condition ,所以你的 eql? 方法可以定义为

    def eql?(other)
      @ip == other.ip && @gateway == other.gateway
    end