Enumeration refers to traversing over objects.
In Ruby, we have Enumerable classes like Array
, Hash
and Range
which get their
enumeration features by including the Enumerable
module.
This Enumerable
module provides various methods
#include?
, #count
, #map
, #select
and #uniq
which we frequently use,
and of course #tally
about which this blog is.
#tally
counts the number of occurrences of an element in a collection and
returns a hash containing the count for all elements.
To know more about Enumerable#tally
that got introduced in Ruby 2.7, check out our previous
blog.
Example
Consider the example of a stationery store. The shopkeeper sells his/her goods on a per-unit basis.
This type of problem is a perfect candidate to leverage our #tally
method to
calculate the total quantity of items sold in a week.
Consider the customers add items one by one to place an order as follows:
Before
Calculating the quantity of each item
As we can see in the above example, the quantity of erasers and sharpeners has increased.
We have concatenated order_one
and order_two
arrays and then called #tally
to get the combined
count of the items ordered.
After
To calculate the total at runtime, Ruby 3.1 Enumerable#tally now accepts an optional hash to count occurrences.
In this case, we can store the running tally of the number of items and pass it to the #tally
method.
As we can see in the above example in Ruby 3.1, we have passed the weekly_tally
hash
as an argument to the #tally
method that stores the count of items.
The count of erasers and sharpeners in order_two
got added to the weekly_tally
hash,
returning the combined quantity for each item.
Note
- A hash with a default value can be passed to the
#tally
method. The keys which are present in the array will ignore the default hash value and keys not present will return the default value instead ofnil
.
- Similarly,
Proc
can be passed to the#tally
method. If the key is present in the arrayProc
will be ignored. For keys not present in the array, theProc
gets executed.
- Keys that are not present in the array are merged with the resulting hash.
For eg.,
first_name
andlast_name
that are not present in theorder
array got merged as it is.
- Keys that are present in the array should only take integer value else it will raise a
TypeError
.