将Ruby中的数组映射为哈希表

4

我有一个二维数组,每行看起来像:

['John', 'M', '34']

我想把它映射到一个哈希数组中,每个哈希看起来像:

{:Name=>"John", :Gender=>"M", :Age=>"34"}

有没有一种优雅的方法来做到这一点?

5个回答

7
array_of_rows.map { |n,g,a| { Name: n, Gender: g, Age: a } }

或者

array_of_rows.map { |row| %i{Name Gender Age}.zip(row).to_h }

他们产生相同的结果,因此选择你认为更清晰的一个。例如,给定以下输入:
array_of_rows = [
  ['John', 'M', '34'],
  ['Mark', 'M', '49']
]

任何一个表达式都将产生这个输出:
[{:Name=>"John", :Gender=>"M", :Age=>"34"}, 
 {:Name=>"Mark", :Gender=>"M", :Age=>"49"}]

1
当我遇到这样的问题时,我通常会问自己,“如果数据在未来发生变化,例如键的数量会发生变化,那该怎么办?”当然最好避免改变代码,所以我更喜欢方案#2,但不会将%i{Name Gender Age}硬编码。 - Cary Swoveland
当然。理想情况下,您应该有一些与数组相关的元数据可供使用,而不是硬编码键名;也许它是从CSV文件中读取的,并且第一行包含可以重新利用的标题。 - Mark Reed

4

4
people = [['John', 'M', '34']]
keys = %i{Name Gender Age}

hashes = people.map { |person| keys.zip(person).to_h }
# => [{:Name=>"John", :Gender=>"M", :Age=>"34"}]

基本上,我将两个数组合并成一个哈希表(一个带有键的数组,一个带有值的数组)的方法是使用 Array#zip。这可以将 [1,2,3][4,5,6] 转换为 [[1,4], [2,5], [3,6]]
通过 to_h,这种结构可以轻松地转换为哈希表。

1
array_of_rows = [
  ['John', 'M', '34'],
  ['Mark', 'M', '49']
]

keys = ['Name', 'Gender', 'Age']

[keys].product(array_of_rows).map { |k,v| k.zip(v).to_h }
  #=> [{"Name"=>"John", "Gender"=>"M", "Age"=>"34"},
  #    {"Name"=>"Mark", "Gender"=>"M", "Age"=>"49"}]

或者

keys_cycle = keys.cycle
array_of_rows.map do |values|
  values.each_with_object({}) { |value, h| h[keys_cycle.next]=value }
do

0

这里还有一种方法可以实现

array_of_rows = [
  ['John', 'M', '34'],
  ['Mark', 'M', '49']
]

keys = [:Name, :Gender, :Age]

array_of_rows.collect { |a| Hash[ [keys, a].transpose] }
#=>[{:Name=>"John", :Gender=>"M", :Age=>"34"}, {:Name=>"Mark", :Gender=>"M", :Age=>"49"}]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接