I cannot get uniq to work with an array of custom class-objects. It
seems
overriding hash is now enough. This is what I mean:
class Obj
attr_reader :name, :number
def initialize(name, number)
@name = name
@number = number
end
def hash
return @name.hash
end
end
a = [Obj.new(“apa”, 1), Obj.new(“apa”, 2), Obj.new(“smisk”, 3)]
=> [#<Obj:0x31baca8 @number=1, @name=“apa”>, #<Obj:0x31bac80 @number=2,
@name=“apa”>, #<Obj:0x31bac58 @number=3, @name=“smisk”>]
a.uniq
=> [#<Obj:0x31baca8 @number=1, @name=“apa”>, #<Obj:0x31bac80 @number=2,
@name=“apa”>, #<Obj:0x31bac58 @number=3, @name=“smisk”>]
But i want only one instance of “apa”, and it doesn’t matter which. Is
there
something else I have to override?
/D
Alle lunedì 29 ottobre 2007, daniel åkerud ha scritto:
return @name.hash
=> [#<Obj:0x31baca8 @number=1, @name=“apa”>, #<Obj:0x31bac80 @number=2,
@name=“apa”>, #<Obj:0x31bac58 @number=3, @name=“smisk”>]
But i want only one instance of “apa”, and it doesn’t matter which. Is
there something else I have to override?
/D
I think you also need to override eql? so that it returns true if the
two objects have the same name:
class Obj
…
def eql? other
@name.eql? other.name
end
end
a = [Obj.new(“apa”, 1), Obj.new(“apa”, 2), Obj.new(“smisk”, 3)]
p a.uniq
=> [#<Obj:0xb7b7f75c @name=“apa”, @number=1>, #<Obj:0xb7b7f57c
@name=“smisk”, @number=3>]
I hope this helps
Stefano
From: daniel åkerud [mailto:[email protected]]
a = [Obj.new(“apa”, 1), Obj.new(“apa”, 2), Obj.new(“smisk”, 3)]
=> [#<Obj:0x31baca8 @number=1, @name=“apa”>, #<Obj:0x31bac80
@number=2, @name=“apa”>, #<Obj:0x31bac58 @number=3, @name=“smisk”>]
a.uniq
=> [#<Obj:0x31baca8 @number=1, @name=“apa”>, #<Obj:0x31bac80
@number=2, @name=“apa”>, #<Obj:0x31bac58 @number=3, @name=“smisk”>]
But i want only one instance of “apa”, and it doesn’t matter
which. Is there something else I have to override?
hmm, that’s a unique requirement for uniq
btw, there was a recent thread on removing dups, wc is similar in a way
to uniq.
anyway, try
~> a.group_by(& :name).map{|_,v|v[0]}
=> [#<Obj:0xba8c90 @name=“smisk”, @number=3>, #<Obj:0xba8d08
@name=“apa”, @number=1>]
sorry, i’m in ruby1.9 box right now. but the idea is that i group the
objects by name, and just get the first on each group.
kind regards -botp
2007/10/29, daniel åkerud [email protected]:
return @name.hash
=> [#<Obj:0x31baca8 @number=1, @name=“apa”>, #<Obj:0x31bac80 @number=2,
@name=“apa”>, #<Obj:0x31bac58 @number=3, @name=“smisk”>]
But i want only one instance of “apa”, and it doesn’t matter which. Is there
something else I have to override?
You can make your life much easier by using Struct:
Obj = Struct.new :name do
attr_accessor :number
def initialize(name, number)
self.name = name
self.number = number
end
end
irb(main):008:0> a = [Obj.new(“apa”, 1), Obj.new(“apa”, 2),
Obj.new(“smisk”, 3)]
=> [#, #, #]
irb(main):009:0> a.uniq
=> [#, #]
Kind regards
robert