idealistikz
idealistikz

Reputation: 1267

Create Hash from Array of Date objects with Month as Key

What is the most efficient way to create a Hash from an Array of Date objects where the month is the key and the value is an Array of dates? Currently, I have the following.

require 'date'

...
start, finish = args.start, args.end # Assume this has been implemented
date_map = {}
(start..finish).map do |date|
    unless date_map.has_key? date.month then date_map[date.month] = [date]
    else date_map[date.month] << date end
end

Is there a more efficient way to accomplish the aforementioned block of code?

Upvotes: 0

Views: 582

Answers (2)

Cary Swoveland
Cary Swoveland

Reputation: 110685

Edit: Just saw @Kyle's answer. Hard to improve on that.

You can write your code like this:

date_map = Hash.new { |h,k| h[k] = [] }
start.upto(finish) { |date| date_map[date.month] << date }

or, more compactly:

date_map = start.upto(finish).with_object(Hash.new { |h,k] h[k] = [] }) \
  { |date, h| h[date.month] << date }

You'll also see it done this way:

date_map = start.upto(finish).with_object({}) { |date, h| 
  (h[date.month] ||= []) << date }

Upvotes: 2

Kyle
Kyle

Reputation: 22268

You can use Enumerable#group_by

(start..finish).group_by(&:month)

Upvotes: 5

Related Questions