将第一行作为下一行哈希的键?

时间:2015-12-14 04:18:07

标签: ruby excel parsing hash

我很难弄清楚如何使用第一行的密钥使下一行成为哈希值。

我有一个像这样结构的数组:

[["id", "name", "address"], [1, "James", "...."], [2, "John", "...."] ]

成为:

[{ id : 1, name: "James", address: "..."}, ...]

我使用了gem" simple_xlsx_reader",我只提取出第一张。

wb.sheets.first.row

并从上面获得了类似的数组输出。

谢谢!

3 个答案:

答案 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