我很难弄清楚如何使用第一行的密钥使下一行成为哈希值。
我有一个像这样结构的数组:
[["id", "name", "address"], [1, "James", "...."], [2, "John", "...."] ]
成为:
[{ id : 1, name: "James", address: "..."}, ...]
我使用了gem" simple_xlsx_reader",我只提取出第一张。
wb.sheets.first.row
并从上面获得了类似的数组输出。
谢谢!
答案 0 :(得分:9)
arr = [["id", "name"], [1, "Jack"], [2, "Jill"]]
[arr.first].product(arr.drop 1).map { |a| a.transpose.to_h }
#=> [{"id"=>1, "name"=>"Jack"}, {"id"=>2, "name"=>"Jill"}]
步骤:
b = [arr.first]
#=> [["id", "name"]]
c = arr.drop 1
#=> [[1, "Jack"], [2, "Jill"]]
d = b.product(c)
#=> [[["id", "name"], [1, "Jack"]], [["id", "name"], [2, "Jill"]]]
d.map { |a| a.transpose.to_h }
#=> [{"id"=>1, "name"=>"Jack"}, {"id"=>2, "name"=>"Jill"}]
传递给d
块的map
的第一个元素是:
a = d.first
[["id", "name"], [1, "Jack"]]
因此,块计算是:
e = a.transpose
#=> [["id", 1], ["name", "Jack"]]
e.to_h
#=> {"id"=>1, "name"=>"Jack"}
答案 1 :(得分:1)
这就是你要找的东西:
DataSet, DataTable and DataView
arr = [["id", "name", "address"], [1, "James", "...."], [2, "John", "...."] ]
keys, *values = arr
values.map {|vals| keys.zip(vals).to_h }
需要两个数组(接收者和参数)和" zips"它们在一起,产生一个元组数组(双元素数组),例如:
Enumerable#zip
keys = [ "foo", "bar", "baz" ]
values = [ 1, 2, 3 ]
p keys.zip(values)
# => [ [ "foo", 1 ], [ "bar", 2 ], [ "baz", 3 ] ]
获取一个元组数组并将其转换为哈希值。
如果您使用的是早于2.1的Ruby版本,则需要使用Array#to_h
。
P.S。如果您想要符号键而不是字符串键,那么您希望在Hash[ *keys.zip(vals) ]
之前执行该转换,例如:
map
或者,如果您不介意修改原始数组:
keys = keys.map(&:to_sym)
答案 2 :(得分:0)
你可以尝试这个非常简单的一行来完成你的工作
arr =[["id", "name", "address"], [1, "James", "add 1"], [2, "John", "add2"] ]
arr.map {|a| arr.first.zip(a).to_h unless a == arr.first }.compact