2016-11-04 127 views
1

假如我有一个数组,看起来像:获取嵌套数组的第一个元素为散列键

[ 
    [["str1"],["val1"],["val2"]], 
    [["str2"], ["val1"], ["val2"], ["val3"]] 
] 

有我得到一个哈希看起来的方式,如:

{ 
    "str1" => [["val1"],["val2"]], 
    "str2" => [["val1"],["val2"],["val3"]] 
} 

回答

3
a.map { |a| [a.first.first, a.drop(1)] }.to_h 
# or 
a.each_with_object({}) {|a, h| h[a.first.first] = a.drop(1) } 
#=> { 
#  "str1"=>[["val1"], ["val2"]], 
#  "str2"=>[["val1"], ["val2"], ["val3"]] 
# } 

如果你不希望有一个单独的数组的每个元素:

Hash[a.map(&:flatten).map { |a| [a.first, a.drop(1)] }] 
#=> {"str1"=>["val1", "val2"], "str2"=>["val1", "val2", "val3"]} 
+1

最后一个不是将每个元素包装在一个数组中,就像前两个一样。 –

+0

谢谢!我使用哈希。我一直试图使用to_h过去两个小时,但无济于事。 – IronCode

+0

@AlexandreAngelim我应该说,但我不希望每个元素包裹在一个数组 – IronCode

2

如果你的数组是arr,你可以写下面的内容。

Marshal.load(Marshal.dump(arr)).map { |a| [a.shift.first, a.map(&:first)] }.to_h 
    #=> {"str1"=>["val1", "val2"], 
    #  "str2"=>["val1", "val2", "val3"]} 

轻微变化将是:

Marshal.load(Marshal.dump(arr)).map { |a| [a.shift.first, a] }.to_h 
    #=> {"str1"=>["val1", "val2"], 
    #  "str2"=>["val1", "val2", "val3"]} 

注:我们正在使用Marshal类做的arr完全相同的副本,以避免修改原始数组。 Object#dupObject#clone在这里不起作用。

+0

''str1“'和'”str2“'应该是关键字,而不是出现在我理解的值 –

+0

谢谢@Andrey。我现在不能测试。我的编辑看起来是否正确? –

+1

是的,它现在产生了预期的结果(测试):) –

0
arr = [ 
    [["str1"],["val1"],["val2"]], 
    [["str2"], ["val1"], ["val2"], ["val3"]] 
] 

arr.each_with_object({}) { |((k), *values), h| h[k]=values } 
    #=> {"str1"=>[["val1"], ["val2"]], "str2"=>[["val1"], ["val2"], ["val3"]]} 

这说明如何Ruby的用于确定块变量的值使用平行分配的可以被有利地使用。

相关问题