我不知道这是一个Hash问题还是一个数组问题,但我不知道为什么在第三个例子中需要使用星号(*)来获得填充数据的哈希值。没有它,它会输出一个空哈希。
# -*- coding: utf-8 -*-
require 'pp'
pp [[:first_name, 'Shane'], [:last_name, 'Harvie']]
# => [[:first_name, "Shane"], [:last_name, "Harvie"]]
pp [[:first_name, 'Shane'], [:last_name, 'Harvie']].flatten
# => [:first_name, "Shane", :last_name, "Harvie"]
pp Hash[*[[:first_name, 'Shane'], [:last_name, 'Harvie']].flatten]
# => {:first_name=>"Shane", :last_name=>"Harvie"}
pp Hash[[[:first_name, 'Shane'], [:last_name, 'Harvie']].flatten]
# => {}
以下是该方法的说明。
--------------------------------------------------------------- Hash::[]
Hash[ [key =>|, value]* ] => hash
From Ruby 1.8
------------------------------------------------------------------------
Creates a new hash populated with the given objects. Equivalent to
the literal +{ _key_, _value_, ... }+. Keys and values occur in
pairs, so there must be an even number of arguments.
Hash["a", 100, "b", 200] #=> {"a"=>100, "b"=>200}
Hash["a" => 100, "b" => 200] #=> {"a"=>100, "b"=>200}
{ "a" => 100, "b" => 200 } #=> {"a"=>100, "b"=>200}
答案 0 :(得分:33)
splat运算符(即*
)将原本是数组的数组转换为散列内的赋值列表。您必须为[]
运算符提供一个实际列表,以转换为哈希的键/值对。 (参见下面的链接到splat运算符的简短描述,实际上可以执行此操作(将数组展开到列表中)或反向(将列表收集到数组中)。)
你在上面的方式,你给Hash[]
奇数个项目,即一个数组。 (想想[[:first_name, 'Shane'], [:last_name, 'Harvie']].flatten
生成的内容。它会产生[:first_name, 'Shane', :last_name, 'Havie']
。)正如您引用的文档所说,[]
运算符必须具有偶数个元素。请注意,以下(虽然无用) 可以工作:
>> Hash[[[:first_name, 'Shane'], [:last_name, 'Harvie']].flatten, 1]
=> {[:first_name, "Shane", :last_name, "Harvie"]=>1}
(我不清楚为什么你在使用上面的代码时没有得到“奇数个Hash参数”错误 - 就像你尝试Hash[1]
时那样。)
一个更简单的例子可能会让它更清晰。首先,传入一个项目,一个数组。使用*
打开数组,以便Hash[]
列出一个项目列表:
>> Hash[['foo', 'bar', 'bizz', 'buzz']]
=> {}
>> Hash[*['foo', 'bar', 'bizz', 'buzz']]
=> {"foo"=>"bar", "bizz"=>"buzz"}
有关更全面的解释,请参阅this blog post。您可能还会发现this short write-up about the splat operator有用。