Reputation: 4935
I only want to update the date element in a hash. i.e.
hash = { 'name': 'Albert', 'date_1': "31-01-2017", 'date_2': "31-01-2017" }
## I only want to update `date_1` and `date_2`.
I have tried
hash.select {|k,v| ['date_1','date_2'].include? k }.transform_values!(&:to_date)
but because I do a select before, it will only return me
{ 'date_1': Tue, 31 Jan 2017, 'date_2': Tue, 31 Jan 2017 }
Any suggestion to do keep other attributes as well as transform the selected key?
i.e. { 'name': 'Albert', 'date_1': Tue, 31 Jan 2017, 'date_2': Tue, 31 Jan 2017 }
Upvotes: 4
Views: 6054
Reputation: 6252
Quick dynamic way
hash = { 'name' => 'Albert', 'date_1' => "31-01-2017", 'date_2' => "31-01-2017" }
hash.map { |k,v| hash[k] = k['date_'] ? v.to_date : v }
Will work on any key that contains date_
, like date_02
, date_1234
, date_lastmonth
, etc
Upvotes: 0
Reputation: 5214
Just update a value for date_1 and date_2:
hash['date_1'] = hash['date_1'].to_date if hash['date_1']
hash['date_2'] = hash['date_2'].to_date if hash['date_2']
or you can do it with each
if you have more a date keys:
date_keys = [:date_1, :date_2]
hash.each do |k,v|
hash[k] = v.to_date if date_keys.include?(k)
end
Upvotes: 5
Reputation: 54303
If you want something a bit more dynamic, without having to hardcode date_1
and date_2
:
require 'date'
hash = { name: 'Albert', date_1: "31-01-2017", date_2: "31-01-2017" }
hash.each do |key, value|
if key.to_s =~ /^date_/ && value.is_a?(String)
hash[key] = Date.strptime(value, '%d-%m-%Y')
end
end
p hash
#=> {:name=>"Albert", :date_1=>#<Date: 2017-01-31 ((2457785j,0s,0n),+0s,2299161j)>, :date_2=>#<Date: 2017-01-31 ((2457785j,0s,0n),+0s,2299161j)>}
Note that for your code :
hash.select {|k,v| ['date_1','date_2'].include? k }.transform_values!(&:to_date)
transform_values!
tries to modify a Hash in place which is only short-lived (the new hash returned by select
). transform_values
would achieve the exact same result.
Upvotes: 1