简体   繁体   中英

Ruby: how to push to a hash inside an array on a CSV

I m new to ruby. I have two csv files, I m using 'csv' library. I can get the arrays from the CSVs but i dont know how to push to a hash inside the first csv.

I get these two arrays from the CSVs:

csv1 = [1,2,{3 => :a},4]
csv2 = [5,6,{7 => :b},8]

And i want the first csv file to look like this:

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

This is one way.

arr1 = [1,2,{ 3 => 'a' },4]
arr2 = [5,6,{ 7 => 'b' },8]

arr1.map do |e|
  case e
  when Hash then e.merge(arr2.select { |e| e.is_a? Hash }.first)
  else e
  end
end
  #=> [1, 2, {3=>"a", 7=>"b"}, 4] 

When

e #=> { 3 => 'a' }

h2 = arr2.select { |e| e.is_a? Hash }.first
  #=> [{ 7 => 'b' }].first
  #    { 7 => 'b' }
e.merge(arr2.select { |e| e.is_a? Hash }.first)
e.merge(h2)
  #=> { 3 => 'a' }.merge({ 7 => 'b' })
  #=> {3=>"a", 7=>"b"}

Here is one more way to do this:

csv1.zip(csv2).collect{|v1, v2| v1.merge(v2) rescue v1 }

We first combine the two arrays using zip

csv1 = [1,2,{3 => :a},4]
csv2 = [5,6,{7 => :b},8]

t = csv1.zip(csv2)
#=> [[1, 5], [2, 6], [{3=>:a}, {7=>:b}], [4, 8]]

Next, we collect the result of merging two elements of the sub-arrays. However, since merge is only supported on Hash , we expect an exception if it is invoked on Fixnum like 1 or 2 - in such cases, we will rescue from the exception by returning value of first element of array.

t = t.collect{|v1, v2| v1.merge(v2) rescue v1 }
#=> [1, 2, {3=>:a, 7=>:b}, 4]

Array#map is an alias of Array#collect - one can use either based on one's preference in the context of code and its readability

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