From: Phrogz Date: 2007-03-06T23:45:08+09:00 Subject: Re: remove duplicates of array of object based on a attribute On Mar 6, 7:27 am, "Phrogz" wrote: > Here's another (assumedly slower) version that doesn't rely on Set: Huh...actually, the hash-based one seems faster than the Set-based one: require 'set' class Array def uniq_by1 seen = Set.new select{ |x| seen.add?( yield( x ) ) } end def uniq_by2 seen = {} select{ |x| !seen[v=yield(x)] && (seen[v]=true) } end end require 'benchmark' a = [ {:a=>1, :d=>1}, {:b=>2}, {:c=>3}, {:a=>1, :d=>3}, {:a=>2, :e=>7}, {:a=>3, :b=>2}, {:a=>1}, {:a=>4}, {:f=>6} ] N = 10_000 Benchmark.bmbm{ |x| x.report( 'with_set' ){ N.times{ a.uniq_by1{ |h| h[:a] } a.uniq_by1{ |h| h[:b] } } } x.report( 'with_hash' ){ N.times{ a.uniq_by2{ |h| h[:a] } a.uniq_by2{ |h| h[:b] } } } } #=> Rehearsal --------------------------------------------- #=> with_set 1.840000 0.030000 1.870000 ( 2.401238) #=> with_hash 1.270000 0.030000 1.300000 ( 1.701307) #=> ------------------------------------ total: 3.170000sec #=> #=> user system total real #=> with_set 1.820000 0.020000 1.840000 ( 2.187477) #=> with_hash 1.250000 0.020000 1.270000 ( 1.555490) (Yes, my laptop is rather old and slow.)