Uniquify an array of hashes in Ruby

Array#uniq is a handy Ruby method that produces an array of distinct elements. So, for example, [1,2,3,3,3].uniq produces [1,2,3].

However, this fails on an array of hashes. For example, [{}, {}].uniq actually produces [{},{}]. That’s not what I wanted, recently.

It turns out that #uniq uses the methods #hash and #eql? to determine uniqueness, and Hash#hash produces the object_id, and {}.eql?({}) produces false.

To solve this, I redefined #hash and #eql? for the hash instances before I put them in the array:

h = {}
class <#dup on this hash will then screw things up, but that’s common to all Ruby eigenclass fun.

However, you could just use a proper class instead of a hash, ’cause this isn’t Perl.

Advertisements

One Comment

  1. Eric
    Posted January 5, 2009 at 7:48 am | Permalink

    Thanks a lot, I needed this for this problem:
    http://projecteuler.net/index.php?section=problems&id=109 :D


One Trackback/Pingback

  1. […] this post, Mike Burns solve this problem by redefining #hash and #eql?. If you are doing this kind of […]

%d bloggers like this: