Search code examples
rubyarraysobjectinstancesuniq

Unique object instances in an array (Ruby)


I have a custom defined class Instruction. Instances are initialized and collected in an array. There are some duplicate (all instance variables identical) instances and I want to filter them out.

class Instruction
    attr_accessor :date, :group, :time
    def initialize(date, group, time)
        @date, @group, @time = date, group, time
    end
end

instructions = Array.new

instructions.push ( Instruction.new('2000-01-01', 'Big', '10am') )
instructions.push ( Instruction.new('2000-01-01', 'Small', '9am') )
instructions.push ( Instruction.new('1999-09-09', 'Small', '4pm') )
instructions.push ( Instruction.new('2000-01-01', 'Small', '9am') )

instructions.uniq.each {|e| puts "date: #{e.date} \tgroup: #{e.group} \ttime: #{e.time}"}

I would expect one of the '2000-01-01', 'Small', '9am' entries removed by .uniq, however I still see the repeated entry in the output.

I have tried adding == and eql? methods to the class definition as follows:

def ==(other)
    other.class == self.class && other.date == self.date && other.group == self.group && other.time == self.time
end
alias :eql? :==

But that didn't work either... Help!


Solution

  • Your use of uniq did not work because, even when the two of the instances of Instruction may share the values of @date, @group, @time, their identity are different. You have to compare the values of these instance variables, not the instance of Instruction itself.

    instructions.uniq{|e| [e.date, e.group, e.time]}