Ruby 两个数组到散列组合中奇怪的乘法器运算符行为

Ruby 两个数组到散列组合中奇怪的乘法器运算符行为,ruby,Ruby,我正在寻找一种将两个数组转换为单个哈希的方法。我发现了这样的东西: 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

我正在寻找一种将两个数组转换为单个哈希的方法。我发现了这样的东西:

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]
 => {}
如果参数看起来相同,是否返回不同的值

我想我一定是遗漏了
*
操作符的某些内容


谢谢。

我认为您的示例中有一个错误,应该是这样的:

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"]

但是从中可以看到,哈希[…]接收多个参数,因此splat操作符帮助分配这些多个参数中的每一个。

*
操作符与这样的数组一起使用时,它被称为splat操作符

可以将其视为删除数组第一级括号的操作符。这非常有用,因为您可以将数组转换为参数列表:

def stuff(x, y, z)
end

a = [1, 2, 3]
stuff(*a) # x,y,z gets assigned 1,2,3
这同样适用于
Hash[]
Hash
上的
[]
运算符接受以下参数:

duck, cow, pig = *["quack","mooh","oing"] #=> ["quack","mooh","oing"]
  • 键值对的参数列表:
    Hash[“a”,1,“b”,2]#=>{“a”=>1,“b”=>2}
  • 表示键值的一个或多个数组对:
    Hash[[“a”,1],“b”,2]]]#=>{“a”=>1,“b”=>2}
  • Hash[]
    not不接受普通平面数组作为参数:

    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运算符的有趣内容。

    这并不是那么神秘:

    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之后的新版本。你的例子可能更老了。

    哦,那是个老例子,好吧!谢谢:)