奇怪的乘数运算符行为在两个数组中进行哈希组合
我一直在寻找一种方法将两个数组转换为单个哈希。 我发现了这样的事情:
a1 = [1,2,3] a2 = [?A, ?B, ?C] Hash[*a1.zip(a2).flatten]
我认为这种语法Hash[a1.zip a2]
,因为Hash[a1.zip a2]
会做同样的事情。 但更重要的是,我不明白需要*
运算符。
我知道它将对象转换为数组或类似的东西(但显然不是以[]
方式)。
当我执行:
a = a1.zip(a2).flatten => [1, "A", 2, "B", 3, "C"] a = *a1.zip(a).flatten => [1, "A", 2, "B", 3, "C"]
什么都没发生,而且对于我所知道的*
运算符,这似乎是正常的行为。
那么,为什么呢
Hash[*a1.zip(a2).flatten] => {1=>"A", 2=>"B", 3=>"C"} Hash[a1.zip(a).flatten] => {}
如果参数看起来相同,则返回不同的值?
我想我一定错过了关于*
运算符的东西。
谢谢。
当*
运算符与数组一起使用时,它被称为splat运算符 。
可以将其视为删除数组周围第一级括号的运算符 。 这非常有用,因为您可以将数组转换为参数列表:
def stuff(x, y, z) end a = [1, 2, 3] stuff(*a) # x,y,z gets assigned 1,2,3
同样适用于Hash[]
。 Hash
上的[]
运算符接受为参数:
- 键值对的参数列表:
Hash["a", 1, "b", 2] #=> { "a" => 1, "b" => 2 }
- 表示键值的数组或数组对:
Hash[ [["a", 1], ["b", 2]] ] #=> { "a" => 1, "b" => 2 }
Hash[]
不接受普通的平面数组作为参数:
Hash[ ["a", 1, "b", 2] ] #=> {}
因此,考虑到这一点,加上我们对splat运算符的理解,您现在可以看到正在发生的事情:
paired_array = a1.zip(a2) => [[1, "A"], [2, "B"], [3, "C"]] plain_array = a1.zip(a2).flatten => [1, "A", 2, "B", 3, "C"] # Per rule 2 above we know this works Hash[paired_array] => {1=>"A", 2=>"B", 3=>"C"} # This won't work Hash[plain_array] => {} # But if we turn the plain_array into an argument list, # then we know per rule 1 above that this will work Hash[*plain_array] => {1=>"A", 2=>"B", 3=>"C"}
现在你可能想知道当你做什么时嘿嘿发生了什么:
a = *plain_array => [1, "A", 2, "B", 3, "C"]
由于我们知道splat运算符有效地剥离括号,我们得到:
a = 1, "A", 2, "B", 3, "C"
…有趣的是有效的Ruby代码,只是再次创建一个数组。
您可以在splat操作符的rubyspec测试用例中阅读有关splat操作符的更多有趣内容。
我认为你的例子中有一个错误,它应该是这样的:
Hash[a1.zip(a2).flatten] #=> {} Hash[*a1.zip(a2).flatten] #=> {1=>"A", 2=>"B", 3=>"C"}
分配模式下的splat运算符将数组转换为多个参数:
duck, cow, pig = *["quack","mooh","oing"] #=> ["quack","mooh","oing"]
实际上它是完全相同的
duck, cow, pig = ["quack","mooh","oing"] #=> ["quack","mooh","oing"]
但是从文档中你可以看到Hash […]接收到多个参数,因此splat运算符有助于分配这些多个参数中的每一个。
这不是那么神秘:
a1 = [1,2,3] a2 = [?A, ?B, ?C] p Hash[*a1.zip(a2).flatten] #{1=>"A", 2=>"B", 3=>"C"}
*
将数组转换为纯粹的参数列表。
但为什么不使用这种语法?
p Hash[a1.zip(a2)]# {1=>"A", 2=>"B", 3=>"C"}
嗯,这是Ruby 1.9.2以来的新function。 你的例子可能更老。
- Rails:在HABTM关系中查找没有连接的行
- 取消删除acts_as_paranoid在设计登录时删除用户
- 使用ARGF在Ruby脚本中捕获Ctrl-D
- 如何将’premailer’与Rails集成
- 我正在Ruby On Rails中创建一个Twitter克隆,我如何对它进行编码,以便’推文’中的’@ …’变成链接?
- 文件系统爬虫 – 迭代错误
- heroku命令存在于这些Ruby版本中?
- 不区分大小写的find_or_create_by_whatever
- Rails 4设计3.1.1 ActionController :: Devise中的UnknownFormat :: RegistrationsController #new