Uniq() Oddity

Would someone please explain this behavior to me?

a = [ { :foo => :bar }, { :foo => :bar } ]

p a #=> [{:foo=>:bar}, {:foo=>:bar}]
p a[0] == a[1] #=> true

why does this next call do nothing?

p a.uniq #=> [{:foo=>:bar}, {:foo=>:bar}]

inefficient work-around

p a.inject([]) { |cp, e| cp.include?(e) ? cp : cp << e } #=>
[{:foo=>:bar}]

James Edward G. II

On Jun 20, 2006, at 15:17, James Edward G. II wrote:

a = [ { :foo => :bar }, { :foo => :bar } ]

p a #=> [{:foo=>:bar}, {:foo=>:bar}]
p a[0] == a[1] #=> true

why does this next call do nothing?

p a.uniq #=> [{:foo=>:bar}, {:foo=>:bar}]

Seems to compare on object id, rather than with ==. I couldn’t
speculate on any more significant answer to ‘why?’

a[0].id == a[1].id
=> true

b = [a[0], a[0]]
b.uniq
=> [{:foo=>:bar}]

matthew smillie.

p a.uniq #=> [{:foo=>:bar}, {:foo=>:bar}]

inefficient work-around

p a.inject([]) { |cp, e| cp.include?(e) ? cp : cp << e } #=>
[{:foo=>:bar}]

James Edward G. II

a = [ { :foo => :bar }, { :foo => :bar } ]

class Hash
def hash
self.to_a.sort.hash
end

def eql? other
    size == other.size && keys.all?{|k| self[k] == other[k]}
end

end

p a.uniq #=> [{:foo=>:bar}]

hth

Simon

“J” == James Edward G. [email protected] writes:

J> p a[0] == a[1] #=> true
J> # why does this next call do nothing?
J> p a.uniq #=> [{:foo=>:bar}, {:foo=>:bar}]

#uniq first create an hash : this mean that it don’t use #== for the
comparison.

moulon% ruby -e ‘a = [{:f =>:b}, {:f => :b}]; p a[0].eql?(a[1]); p
a[0]==a[1]’
false
true
moulon%

Guy Decoux

On 6/20/06, James Edward G. II [email protected] wrote:

p a.inject([]) { |cp, e| cp.include?(e) ? cp : cp << e } #=>
[{:foo=>:bar}]

James Edward G. II

Doesn’t seem to work for hashes at all:
irb(main):005:0> [{}, {}].uniq
=> [{}, {}]

Yet:
irb(main):008:0> {} == {}
=> true

Can any body help me with How to “unsubscribe” from the ruby talk
mailing list.

Thanks.

On Jun 20, 2006, at 9:26 AM, Kroeger, Simon (ext) wrote:

p a.uniq #=> [{:foo=>:bar}, {:foo=>:bar}]
def hash
self.to_a.sort.hash
end

def eql? other
    size == other.size && keys.all?{|k| self[k] == other[k]}
end

end

p a.uniq #=> [{:foo=>:bar}]

So which one is uniq() really using? eql?()?

James Edward G. II

On Jun 20, 2006, at 9:25 AM, Matthew S. wrote:

On Jun 20, 2006, at 15:17, James Edward G. II wrote:

a = [ { :foo => :bar }, { :foo => :bar } ]

p a #=> [{:foo=>:bar}, {:foo=>:bar}]
p a[0] == a[1] #=> true

why does this next call do nothing?

p a.uniq #=> [{:foo=>:bar}, {:foo=>:bar}]

Seems to compare on object id, rather than with ==.

Can’t be that:

str1 = “a”
=> “a”

str2 = “a”
=> “a”

str1.object_id == str2.object_id
=> false

[str1, str2].uniq
=> [“a”]

James Edward G. II

On 6/20/06, Matthew S. [email protected] wrote:

speculate on any more significant answer to ‘why?’

a[0].id == a[1].id
=> true

b = [a[0], a[0]]
b.uniq
=> [{:foo=>:bar}]

Not comparing on id:

irb(main):006:0> [[‘a’],[‘a’]].each{|ar| puts ar.id}
99017932
99017908
=> [[“a”], [“a”]]
irb(main):007:0> [[‘a’],[‘a’]].uniq
=> [[“a”]]
irb(main):008:0>

On Jun 20, 2006, at 9:27 AM, ts wrote:

“J” == James Edward G. [email protected] writes:

J> p a[0] == a[1] #=> true
J> # why does this next call do nothing?
J> p a.uniq #=> [{:foo=>:bar}, {:foo=>:bar}]

#uniq first create an hash : this mean that it don’t use #== for the
comparison.

Interesting. Thank you for the information.

James Edward G. II

From: James Edward G. II [mailto:[email protected]]
Sent: Tuesday, June 20, 2006 4:32 PM

p a.uniq #=> [{:foo=>:bar}]

So which one is uniq() really using? eql?()?

James Edward G. II

both, uniq creates a hash from the array.
Iterating over the array it deletes from the hash and removes
values from the array if there is no such element in the hash
left. To find the element in the hash both methods are necessary.

cheers

Simon

On Jun 20, 2006, at 9:45 AM, Kroeger, Simon (ext) wrote:

both, uniq creates a hash from the array.
OK, let me expand my question slightly: why are hash() and eql?()
not meaningfully defined for Hash?

Doesn’t Array.hash just aggregate the hash() of its elements? Why
could Hash not do the same?

Thanks all for the information.

James Edward G. II

On Tue, Jun 20, 2006 at 11:56:21PM +0900, James Edward G. II wrote:

So which one is uniq() really using? eql?()?

both, uniq creates a hash from the array.

OK, let me expand my question slightly: why are hash() and eql?()
not meaningfully defined for Hash?

Doesn’t Array.hash just aggregate the hash() of its elements? Why
could Hash not do the same?

There’s also Hash#default and Hash#default_proc to take in mind.
And you can’t rely on Proc#hash and friends…
Otherwise, it’s trivially implementable.

On Jun 20, 2006, at 10:29 AM, Hamid Rasoulian wrote:

Can any body help me with How to “unsubscribe” from the ruby talk
mailing list.

Thanks.

To unsubscribe ML [email protected], send “unsubscribe” in
the mail body
to the address [email protected]. Also you can send “#
unsubscribe”.
“#” is prepended in fml documents for some historically reasons. “#”
is NOT NEEDED in almost all cases but fml can accepct commands with or
without ‘#’. Please ignore this in default configuration.

Hamid Rasoulian wrote:

Can any body help me with How to “unsubscribe” from the ruby talk
mailing list.

The mail header of every ruby-talk message includes such instructions.

Look for the List-Unsubscribe header:

mailto:[email protected]?body=unsubscribe

Thanks.

You’re welcome.


James B.

“Design depends largely on constraints.”

  • Charles Eames

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs