Isolating non-unique items in an array

But of course, other posts in this thread are likely faster.

How much faster? Much.

class Array
  def dcount1
    Hash[ *uniq.map{ |e|
      if ( count = grep(e).size ) > 1
        [e, count]
      end
    }.compact.flatten ]
  end
  
  def dcount2
    inject( Hash.new(0) ){ |counts,e|
      counts[e]+=1
      counts
    }.reject{ |e,count|
      count==1
    }
  end
  
  def dcount3
    counts = Hash.new(0)
    each{ |e| counts[e]+=1 }
    counts.reject{ |e,count| count==1 }
  end
  
end

a = %w| a a a a b c d d e b c f g h h i j k l l m n o p a b f h l m a a
c d d b h l l m h |

runs = 10000
require 'benchmark'
Benchmark.bmbm{ |x|
  x.report( 'dcount1' ){
    runs.times{ a.dcount1 }
  }
  x.report( 'dcount2' ){
    runs.times{ a.dcount2 }
  }
  x.report( 'dcount3' ){
    runs.times{ a.dcount3 }
  }
}

#=> user system total real
#=> dcount1 5.641000 0.000000 5.641000 ( 5.641000)
#=> dcount2 2.000000 0.015000 2.015000 ( 2.016000)
#=> dcount3 1.360000 0.016000 1.376000 ( 1.375000)

···

From: Gavin Kistner