KC S
KC S

Reputation: 4935

Update certain key in hash

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

Answers (3)

yodog
yodog

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

Alex Kojin
Alex Kojin

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

Eric Duminil
Eric Duminil

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

Related Questions