红宝石数组中的唯一对象

Den*_*s L 1 ruby

该程序应该只生产唯一的飞机,它重复元素数组。uniq方法无济于事。

class Airplane

    attr_accessor :model        

    def initialize(model) 
        @model = model
    end
end

models  =   [ "Boeing 777-300ER",
              "Boeing 737-800",
              "Airbus ?330-200", 
              "Airbus ?330-300",
              "Airbus ?321",
              "Airbus A320",
              "Sukhoi SuperJet 100"]
planes = []

150.times do

    model = models[rand(0..6)]
    plane = Airplane.new(model)

    planes << plane 
Run Code Online (Sandbox Code Playgroud)

在这里尝试#飞机= planes.uniq没有帮助

    break if models.length == planes.length
end

# result
planes.uniq.each do |plane|   # <<<< uniq doesn't help
    puts "Model: #{plane.model}"
end
Run Code Online (Sandbox Code Playgroud)

Ama*_*dan 8

除非另有说明,否则两个对象都不相同:

Object.new.eql?(Object.new)
# => false
Run Code Online (Sandbox Code Playgroud)

因此,在#uniq所有Airplane情况下,所有150个实例都是唯一的,没有重复。

解决此问题的最简单方法是为以下项提供唯一性标准#uniq

planes.uniq(&:model)
Run Code Online (Sandbox Code Playgroud)

另一种方法是定义“重复”对Airplane类的含义:

class Airplane
  attr_accessor :model        

  def initialize(model) 
    @model = model
  end

  def ==(other)
    other.class == self.class && other.model == self.model
  end

  alias_method :eql?, :==

  def hash
    self.model.hash
  end
end
Run Code Online (Sandbox Code Playgroud)

但是,在所有情况下,此解决方案都将使两架相同型号的飞机成为同一架飞机,这可能会在其他地方带来意想不到的后果。

  • [Ruby:为什么每次覆盖#eql时都需要覆盖#hash?](/sf/ask/3847291801/ -eql-is-overridden)(对“哈希”解释的逻辑相同,在其中为“ #uniq”成立,其文档中明确提到了“ #eql?”和“ #hash”。) (2认同)