I'm trying to transform a two dimensional array to an array of hashes. Here is my array:
[[8765, 105191, 2.0, 1582.1], [4321, 62870, 2.0, 603.24], [1234, 62870, 2.0, 500.24]]
I'm trying to transform this to an array of hash values. Something like this:
[{"sales_user_id"=>"8765", "user_id"=>"105191", "month"=>"2", "sum"=>"1582.1"},
{"sales_user_id"=>"4321", "user_id"=>"62870", "month"=>"2", "sum"=>"603.24"},
{"sales_user_id"=>"1234", "user_id"=>"62870", "month"=>"2", "sum"=>"500.24"}]
I'm breaking down each array and assigning a key to the values in the array. I'm still a little new to ruby and I'm not sure where to start.
This is pretty straightforward with Enumerable#zip
:
values = [ [ 8765, 105191, 2.0, 1582.1 ],
[ 4321, 62870, 2.0, 603.24 ],
[ 1234, 62870, 2.0, 500.24 ] ]
keys = %w[sales_user_id user_id month sum]
p values.map {|arr| keys.zip(arr).to_h }
# => [ { "sales_user_id" => 8765, "user_id" => 105191, "month" => 2.0, "sum" => 1582.1 },
# { "sales_user_id" => 4321, "user_id" => 62870, "month" => 2.0, "sum" => 603.24 },
# { "sales_user_id" => 1234, "user_id" => 62870, "month" => 2.0, "sum" => 500.24 } ]
arr = [[8765, 105191, 2.0, 1582.1 ],
[4321, 62870, 2.0, 603.24],
[1234, 62870, 2.0, 500.24]]
keys = ["sales_user_id", "user_id", "month", "sum"]
First way
[keys].product(arr).map { |a| a.transpose.to_h }
#=> [{"sales_user_id"=>8765, "user_id"=>105191, "month"=>2.0, "sum"=>1582.1},
# {"sales_user_id"=>4321, "user_id"=> 62870, "month"=>2.0, "sum"=>603.24},
# {"sales_user_id"=>1234, "user_id"=> 62870, "month"=>2.0, "sum"=>500.24}]
The steps:
enum = [keys].product(arr)
#=> #<Enumerator:
# [
# [["sales_user_id", "user_id", "month", "sum"], [8765, 105191, 2.0, 1582.1]],
# [["sales_user_id", "user_id", "month", "sum"], [4321, 62870, 2.0, 603.24]],
# [["sales_user_id", "user_id", "month", "sum"], [1234, 62870, 2.0, 500.24]]
# ]:map>
a = enum.next
#=> [["sales_user_id", "user_id", "month", "sum"], [8765, 105191, 2.0, 1582.1]]
c = a.transpose
#=> [["sales_user_id", 8765], ["user_id", 105191], ["month", 2.0], ["sum", 1582.1]]
c.to_h
#=> {"sales_user_id"=>8765, "user_id"=>105191, "month"=>2.0, "sum"=>1582.1}
a = enum.next
#=> [["sales_user_id", "user_id", "month", "sum"], [4321, 62870, 2.0, 603.24]]
c = a.transpose
#=> [["sales_user_id", 4321], ["user_id", 62870], ["month", 2.0], ["sum", 603.24]]
c.to_h
#=> {"sales_user_id"=>4321, "user_id"=>62870, "month"=>2.0, "sum"=>603.24}
a = enum.next
#=> [["sales_user_id", "user_id", "month", "sum"], [1234, 62870, 2.0, 500.24]]
c = a.transpose
#=> [["sales_user_id", 1234], ["user_id", 62870], ["month", 2.0], ["sum", 500.24]]
c.to_h
#=> {"sales_user_id"=>1234, "user_id"=>62870, "month"=>2.0, "sum"=>500.24}
Second way
arr.map do |a|
ad = a.dup
{ "sales_user_id"=>ad.shift, "user_id"=>ad.shift, "month"=>ad.shift, "sum"=>ad.shift }
end
#=> [{"sales_user_id"=>8765, "user_id"=>105191, "month"=>2.0, "sum"=>1582.1},
# {"sales_user_id"=>4321, "user_id"=> 62870, "month"=>2.0, "sum"=>603.24},
# {"sales_user_id"=>1234, "user_id"=> 62870, "month"=>2.0, "sum"=>500.24}]
Also consider using a Struct if you have a fixed set of values per object. Can be used pretty much as a hash.
User = Struct.new(:sales_user_id, :user_id, :month, :sum)
array = [[8765, 105191, 2.0, 1582.1], [4321, 62870, 2.0, 603.24], [1234, 62870, 2.0, 500.24]]
users = array.map {|values| User.new *values}
p users #=> [#<struct User sales_user_id=8765, user_id=105191, month=2.0, sum=1582.1>, #<struct User sales_user_id=4321, user_id=62870, month=2.0, sum=603.24>, #<struct User sales_user_id=1234, user_id=62870, month=2.0, sum=500.24>]
p users.first.user_id #=> 105191
p users.first['user_id'] #=> 105191
p users.first[:user_id] #=> 105191
Here's one way to do it that uses .collect
to iterate over the outer array and construct a hash for each inner array:
values = [[8765, 105191, 2.0, 1582.1],
[4321, 62870, 2.0, 603.24],
[1234, 62870, 2.0, 500.24]]
result = values.collect do |array|
{
"sales_user_id" => array[0].to_s,
"user_id" => array[1].to_s,
"month" => array[2].to_i.to_s,
"sum" => array[3].to_s
}
end
result
:
[{"sales_user_id"=>"8765", "user_id"=>"105191", "month"=>"2", "sum"=>"1582.1"},
{"sales_user_id"=>"4321", "user_id"=>"62870", "month"=>"2", "sum"=>"603.24"},
{"sales_user_id"=>"1234", "user_id"=>"62870", "month"=>"2", "sum"=>"500.24"}]
It also uses .to_s
and .to_i
to coerce the result into the values in the question (like 8765
to "8765"
and 2.0
to "2"
).
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.