*在参数位置的含义

时间:2014-06-20 17:03:06

标签: ruby splat

假设arr是数组[[1,3],[2,5],[3,8]]。我想知道*是什么意思。这是什么意思?

hash = Hash[*arr.flatten] # => {1=>3, 2=>5, 3=>8}

我尝试了以下

arr.flatten # => [1, 3, 2, 5, 3, 8]
Hash[arr.flatten] # => {}
Hash[*a.flatten] # => {1=>3, 2=>5, 3=>8}

2 个答案:

答案 0 :(得分:1)

以下是解释

执行array.flatten时,它将为您提供一个展平数组,其中所有内部数组都是板条。现在您将此展平数组放在Hash::[]方法中。但Hash::[]支持以下结构:

Hash[ key, value, ... ] → new_hash 
# or
Hash[ [ [key, value], ... ] ] → new_hash

现在array.flatten为您提供[1, 3, 2, 5, 3, 8]。现在,您将此数组放在Hash[] Hash[[1, 3, 2, 5, 3, 8]]内。现在与上述2个结构进行比较。它们中的任何一个匹配吗? NO 。所以你需要再次展开内部数组,因此需要(splatted operator)*来展开内部数组。

现在你做了Hash[*[1, 3, 2, 5, 3, 8]],它提供了Hash[1, 3, 2, 5, 3, 8]。现在再次检查以上2个结构。它与2中的任何一个匹配吗?这次,第一次。所以你得到了所需的哈希{1=>3, 2=>5, 3=>8}

顺便说一下,你不需要splat,因为当你将 array 直接放在Hash::[]内时,第二个construt完全匹配。

array = [[1,3],[2,5],[3,8]]
Hash[array] # => {1=>3, 2=>5, 3=>8}

上述方法有效,因为Hash[array]表示Hash[[[1,3],[2,5],[3,8]]]正是文档建议的第二个结构

阅读some examples,了解 splatting 在Ruby中的工作方式。

还有另一种结构: -

 Hash[ object ] → new_hash

我认为告诉你为什么得到{}也很重要。 Hash[[1, 3, 2, 5, 3, 8]]与文档中最后一种类型的构造相同。医生说 -

  

第二个和第三个​​形式采用单个参数,它是一个键值对数组或一个可转换为哈希值的对象。

因此。 [1,3,2,5,3,8] Array对象不可转换Hash。目前,如果按照第三个构造的对象,它会为您提供空哈希。但它会在未来版本的版本中引发错误。请参阅下面的警告

[1] pry(main)> Hash[[1,2]]
(pry):1: warning: wrong element type Fixnum at 0 (expected array)
(pry):1: warning: ignoring wrong elements is deprecated, remove them explicitly
(pry):1: warning: this causes ArgumentError in the next release
(pry):1: warning: wrong element type Fixnum at 1 (expected array)
(pry):1: warning: ignoring wrong elements is deprecated, remove them explicitly
(pry):1: warning: this causes ArgumentError in the next release
=> {}

我的Ruby版本是:

ruby 2.0.0p451 (2014-02-24 revision 45167) [i686-linux]

答案 1 :(得分:0)

当您将参数传递给Hash类时,可以将其放在括号中......

Hash(arr.flatten)

或没有......

Hash arr.flatten

在任何一种情况下,Hash都接受参数,如果它是一个具有偶数个元素的数组,它将创建一个散列,其中奇数元素是键,偶数元素是值。

哈希也可以使用方括号来执行类似的操作

Hash[1, 2]
=> {1=>2}

但是,当你这样做时......

Hash[arr.flatten]

您正在将数组传递到数组中,以便获得意外结果。

当你这样做时......

Hash[*arr.flatten] 

你是说取数组arr.flatten并传递它,而不是作为数组传递,而是作为方法的单独参数。

所以Hash[arr.flatten]实际上是Hash[[1, 3, 2, 5, 3, 8]](包含一个数组的数组是一个数组),而Hash[*arr.flatten]实际上是Hash[1, 3, 2, 5, 3, 8](一个包含六个元素的数组)

有趣的是,[]方法可以采用包含键,值对数组的数组,所以..

Hash[arr]

工作正常!你不必压平或扯掉任何东西。