Ruby Program to Find Frequency of Elements
Use Ruby's
each_with_object(Hash.new(0)) to count frequencies like this: array.each_with_object(Hash.new(0)) { |e, freq| freq[e] += 1 }.Examples
Input[1, 2, 2, 3, 3, 3]
Output{1=>1, 2=>2, 3=>3}
Input['apple', 'banana', 'apple', 'orange', 'banana', 'banana']
Output{"apple"=>2, "banana"=>3, "orange"=>1}
Input[]
Output{}
How to Think About It
To find how many times each element appears, start with an empty count for each item. Then look at each element one by one and add one to its count. At the end, you have a list showing each element and how many times it showed up.
Algorithm
1
Create an empty dictionary to hold counts.2
For each element in the list, check if it is already in the dictionary.3
If it is, increase its count by one.4
If it is not, add it to the dictionary with count one.5
After checking all elements, return the dictionary with counts.Code
ruby
array = [1, 2, 2, 3, 3, 3] frequency = array.each_with_object(Hash.new(0)) do |element, freq| freq[element] += 1 end puts frequency
Output
{1=>1, 2=>2, 3=>3}
Dry Run
Let's trace the array [1, 2, 2, 3, 3, 3] through the code
1
Initialize frequency hash
frequency = {} with default 0
2
Process element 1
frequency[1] = 0 + 1 = 1
3
Process element 2
frequency[2] = 0 + 1 = 1
4
Process element 2 again
frequency[2] = 1 + 1 = 2
5
Process element 3
frequency[3] = 0 + 1 = 1
6
Process element 3 again
frequency[3] = 1 + 1 = 2
7
Process element 3 again
frequency[3] = 2 + 1 = 3
| Element | Frequency Hash |
|---|---|
| 1 | {1=>1} |
| 2 | {1=>1, 2=>1} |
| 2 | {1=>1, 2=>2} |
| 3 | {1=>1, 2=>2, 3=>1} |
| 3 | {1=>1, 2=>2, 3=>2} |
| 3 | {1=>1, 2=>2, 3=>3} |
Why This Works
Step 1: Create a hash with default 0
Using Hash.new(0) means any new key starts with count zero automatically.
Step 2: Iterate over each element
We look at each element in the array one by one to count them.
Step 3: Increment count for each element
For each element, we add one to its current count in the hash.
Alternative Approaches
Using Enumerable#group_by and transform_values
ruby
array = [1, 2, 2, 3, 3, 3] frequency = array.group_by { |e| e }.transform_values(&:count) puts frequency
This groups elements first, then counts each group; it is readable but may use more memory.
Using a manual loop and hash
ruby
array = [1, 2, 2, 3, 3, 3] frequency = {} array.each do |e| frequency[e] = frequency.fetch(e, 0) + 1 end puts frequency
This uses explicit checks and updates, good for understanding but more verbose.
Complexity: O(n) time, O(k) space
Time Complexity
The program loops through the array once, so time grows linearly with the number of elements.
Space Complexity
It stores counts for each unique element, so space depends on the number of unique items.
Which Approach is Fastest?
Using each_with_object with Hash.new(0) is efficient and concise compared to grouping methods.
| Approach | Time | Space | Best For |
|---|---|---|---|
| each_with_object + Hash.new(0) | O(n) | O(k) | Fast and memory efficient for counting |
| group_by + transform_values | O(n) | O(n) | Readable but uses more memory |
| manual loop with fetch | O(n) | O(k) | Good for beginners to understand counting |
Use
Hash.new(0) to avoid checking if keys exist before incrementing counts.Beginners often forget to initialize the hash with default 0, causing errors when incrementing counts.