From: Ross Bamford Date: 2006-10-13T01:04:02+09:00 Subject: Re: Isolating non-unique items in an array On Fri, 2006-10-13 at 00:24 +0900, Jason Burgett wrote: > I'm basically trying to the opposite of .uniq Let's say I have an array: > > ["a", "a", "a", "b", "c", "d", "d"] > > I would like to boil this down by first tossing the values that only > appear once. Which leaves me with: > > ["a", "a", "a", "d", "d"] > > Then I need to somehow determine that "a" appears 3 times and "d" > appears 2 times. Any help would be great. Thanks. > There are bound to be better ways, but you could try something like: a = ["a", "a", "a", "b", "c", "d", "d"] # => ["a", "a", "a", "b", "c", "d", "d"] hsh = a.inject(Hash.new{|h,k| h[k] = 0}) {|h,v| h[v] += 1 ; h}.reject! {|k,v| v == 1} # => {"a"=>3, "d"=>2} hsh['a'] # => 3 hsh['d'] # => 2 Depending on how you're using the results, You could also run a second inject to reverse the lookup: rhsh = hsh.inject(Hash.new { |h,k| h[k] = [] }) { |h,(k,v)| h[v] << k ; h } # => {2=>["d"], 3=>["a"]} (2..rhsh.keys.max).each { |i| puts "count #{i}: #{rhsh[i]}" } # count 2: d # count 3: a If you went with this way, I guess you could forget about getting rid of the 1s with reject!, since you could just ignore the 1 key in the rhsh... -- Ross Bamford - rosco@roscopeco.REMOVE.co.uk