Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to count duplicate elements in a Ruby array

Tags:

arrays

ruby

I have a sorted array:

[   'FATAL <error title="Request timed out.">',   'FATAL <error title="Request timed out.">',   'FATAL <error title="There is insufficient system memory to run this query.">' ] 

I would like to get something like this but it does not have to be a hash:

[   {:error => 'FATAL <error title="Request timed out.">', :count => 2},   {:error => 'FATAL <error title="There is insufficient system memory to run this query.">', :count => 1} ] 
like image 441
Željko Filipin Avatar asked Feb 20 '09 14:02

Željko Filipin


People also ask

How do you count duplicates in array?

The idea is to initialize another array(say count[]) with the same size N and initialize all the elements as 0. Then count the occurrences of each element of the array and update the count in the count[]. Print all the element whose count is greater than 1.

How do you check if there are duplicates in an array Ruby?

select { array. count } is a nested loop, you're doing an O(n^2) complex algorithm for something which can be done in O(n). You're right, to solve this Skizit's question we can use in O(n); but in order to find out which elements are duplicated an O(n^2) algo is the only way I can think of so far.

How do you count items in an array in Ruby?

Ruby | Array count() operation Array#count() : count() is a Array class method which returns the number of elements in the array. It can also find the total number of a particular element in the array. Syntax: Array. count() Parameter: obj - specific element to found Return: removes all the nil values from the array.

What is .first in Ruby?

first is a property of an array in Ruby that returns the first element of an array. If the array is empty, it returns nil. array. first accesses the first element of the array, i.e., the element at index 0 .


2 Answers

The following code prints what you asked for. I'll let you decide on how to actually use to generate the hash you are looking for:

# sample array a=["aa","bb","cc","bb","bb","cc"]  # make the hash default to 0 so that += will work correctly b = Hash.new(0)  # iterate over the array, counting duplicate entries a.each do |v|   b[v] += 1 end  b.each do |k, v|   puts "#{k} appears #{v} times" end 

Note: I just noticed you said the array is already sorted. The above code does not require sorting. Using that property may produce faster code.

like image 57
nimrodm Avatar answered Sep 30 '22 06:09

nimrodm


You can do this very succinctly (one line) by using inject:

a = ['FATAL <error title="Request timed out.">',       'FATAL <error title="Request timed out.">',       'FATAL <error title="There is insufficient ...">']  b = a.inject(Hash.new(0)) {|h,i| h[i] += 1; h }  b.to_a.each {|error,count| puts "#{count}: #{error}" } 

Will produce:

1: FATAL <error title="There is insufficient ..."> 2: FATAL <error title="Request timed out."> 
like image 33
vladr Avatar answered Sep 30 '22 05:09

vladr