Reputation: 28803
I have an array of hashes that contains a date and total key.
For example:
hash = [{
"Date"=>"01/01/2016",
"Total"=>10
},{
"Date"=>"02/01/2016",
"Total"=>20
},{
"Date"=>"03/01/2016",
"Total"=>30
},{
"Date"=>"04/01/2016",
"Total"=>40
},{
"Date"=>"05/01/2016",
"Total"=>50
}]
What I want to do is pass two dates to a method that then returns only hashes whose dates are either matching or between the two dates.
So for example:
get_data(startDate, endDate)
end
Where the startDate and endDate are '02/01/206' and 04/01/2016
Would return:
{
"Date"=>"02/01/2016",
"Total"=>20
},{
"Date"=>"03/01/2016",
"Total"=>30
},{
"Date"=>"04/01/2016",
"Total"=>40
}
Upvotes: 1
Views: 576
Reputation: 110685
I endorse @Steve's answer, but would like to point out you could use Ruby's somewhat obscure flip-flop operator.
Below, arr
is the array of hashes in your example.
require 'date'
h = arr.each_with_object({}) { |g,h| h[Date.strptime(g["Date"], '%d/%m/%Y')] = g }
#=> {#<Date: 2016-01-01 ((2457389j,0s,0n),+0s,2299161j)>=>
# {"Date"=>"01/01/2016", "Total"=>10},
# #<Date: 2016-01-02 ((2457390j,0s,0n),+0s,2299161j)>=>
# {"Date"=>"02/01/2016", "Total"=>20},
# #<Date: 2016-01-03 ((2457391j,0s,0n),+0s,2299161j)>=>
# {"Date"=>"03/01/2016", "Total"=>30},
# #<Date: 2016-01-04 ((2457392j,0s,0n),+0s,2299161j)>=>
# {"Date"=>"04/01/2016", "Total"=>40},
# #<Date: 2016-01-05 ((2457393j,0s,0n),+0s,2299161j)>=>
# {"Date"=>"05/01/2016", "Total"=>50}}
range = Date.strptime('02/01/2016', '%d/%m/%Y')..Date.strptime('04/01/2016', '%d/%m/%Y')
#=> #<Date: 2016-01-02 ((2457390j,0s,0n),+0s,2299161j)>..
# #<Date: 2016-01-04 ((2457392j,0s,0n),+0s,2299161j)>
The flip-flop operator is used to determine the keys that fall within the given range:
keeper_keys = h.keys.sort.select { |d| range.include?(d) .. true ? true : false }
#=> [#<Date: 2016-01-02 ((2457390j,0s,0n),+0s,2299161j)>,
# #<Date: 2016-01-03 ((2457391j,0s,0n),+0s,2299161j)>,
# #<Date: 2016-01-04 ((2457392j,0s,0n),+0s,2299161j)>]
h.select { |k,_| keeper_keys.include?(k) }.values
#=> [{"Date"=>"02/01/2016", "Total"=>20},
# {"Date"=>"03/01/2016", "Total"=>30},
# {"Date"=>"04/01/2016", "Total"=>40}]
Upvotes: 0
Reputation: 36860
def get_data(start_date, end_date, hash)
hash.select{|entry| entry["Date"].to_date.between?(start_date.to_date, end_date.to_date) }
end
Upvotes: 2