我一直在寻找一种将两个数组转换为单个哈希的方法。我找到了类似的东西:
a1 = [1,2,3]
a2 = [?A, ?B, ?C]
Hash[*a1.zip(a2).flatten]
我认为这种语法有点奇怪,因为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]
=> {}
如果参数看起来相同,则返回不同的值?
我想我必须遗漏一些关于*
运算符的内容。
感谢。
答案 0 :(得分:4)
当*
运算符与数组一起使用时,它被称为 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代码,只是再次创建一个数组。
您可以在rubyspec test case for the splat operator中阅读有关splat运算符的更多有趣内容。
答案 1 :(得分:2)
我认为你的例子中有一个错误,它应该是这样的:
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"]
但是从documentation可以看出Hash [...]接收到多个参数,因此splat运算符有助于分配这些多个参数。
答案 2 :(得分:1)
这不是那么神秘:
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以来它是新的。你的例子可能比较老了。