简体   繁体   中英

Add a key value pair to all hashes in an array of hashes

I have an Array of hashes.

results = [{a:1, b:2},{a:3, b:4}]

I want to add an element "c" to all hashes so I end up with:

results = [{a:1, b:2, c:"newvalue"},{a:3, b:4, c:"newvalue"}]

I'm trying to work a more efficent way of doign this than cycling through the array and doing it one by one.

Should clarify. By "not iterating" I simply mean not writing

results.each do |a|
  a[:c] = "newvalue"
end

Perhaps the question is a little dumb, but was just thinking there should be something similar to ActiveRecord style

results.update_all(c:"new_value")

which is infinitely more efficent/quicker than iterating through ... It may be that with an array there's no difference....

or the difference between

array.map{|a| [a,2]}

and

array.product([2])

Try this.

results.each {|h| h[:c]="newvalue" unless h.include? :c}

it will add :c value if not exists.

and if you want to add for all elements without check it.

results.each {|h| h[:c]="newvalue"}

if you don't to iterate you can ask doing fetch method when you ask for the value.

results.fetch(:c, "newvalue")

and If you need that value on the hash and you won't to iterate array, you could add default value when you create hashes with (default)

Given

results = [{a:1, b:2},{a:3, b:4}]

Then

results.map { |v| v['c'] = 'newvalue'; v }
# => [{:a=>1, :b=>2, "c"=>"newvalue"}, {:a=>3, :b=>4, "c"=>"newvalue"}]

When 'newvalue' isn't static

merge_in = ['newvalue1', 'newvalue2']

Then

results.map.with_index { |hash, i| hash['c'] = merge_in[i]; hash }
# => [{:a=>1, :b=>2, "c"=>"newvalue1"}, {:a=>3, :b=>4, "c"=>"newvalue2"}]

I'm not able to estimate what will be @Cary Swoveland's critic on my answer, but let me try :)

You have an array of hashes. For my ruby version (1.8.7) I modified it a bit.

irb(main):003:0> results = [{'a'=>1, 'b'=>2},{'a'=>3, 'b'=>4}]

For adding a new key-value pair to each of these array elements, you have to iterate over them.

In ruby there are lots of ways to do it, but one of them may give you correct understanding on the subject.

irb(main):007:0> results.each do |h| # get each element (key-value pairs) of results array  
irb(main):008:1* h['c'] = 'newvalue' #add a new pair to them
irb(main):009:1> end
=> [{"c"=>"newvalue", "b"=>2, "a"=>1}, {"c"=>"newvalue", "b"=>4, "a"=>3}]
# same as results.each {|h| h['c'] ="newvalue"}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM