迭代如何在Ruby中工作?

5 ruby loops block

我最近开始编写Ruby,我对块参数有误解.以下面的代码为例:

h = { # A hash that maps number names to digits
:one => 1, # The "arrows" show mappings: key=>value
:two => 2 # The colons indicate Symbol literals
}
h[:one] # => 1. Access a value by key
h[:three] = 3 # Add a new key/value pair to the hash
h.each do |key,value| # Iterate through the key/value pairs
  print "#{value}:#{key}; " # Note variables substituted into string
end # Prints "1:one; 2:two; 3:three; "
Run Code Online (Sandbox Code Playgroud)

据我所知,一般的散列功能,但我不知道如何valuekey设置任何东西.它们被指定为块中的参数,但哈希从不以任何方式与这些参数相关联.

Jon*_*eet 6

h由于您调用h.each而不是调用each其他内容,hash()与循环相关联.它有效地说,"对于每个键/值对h,让key迭代变量成为键,让value迭代变量为值,然后执行循环体."

如果这没有帮助,请看一下这个页面each ......如果你能解释一下你发现哪些比较棘手的问题,我们可能会提供更多帮助.(好吧,其他人也许可以.我真的不懂Ruby.)


Swa*_*and 6

这是Ruby块(Ruby的匿名函数名称)语法.并且key,value只是传递给匿名函数的参数.

Hash#each取一个参数:一个有2个参数的函数,keyvalue.

因此,如果我们将其分解为部分,那么代码的这一部分:h.each正在调用each函数h.这部分代码:

do |key, value| # Iterate through the key/value pairs
  print "#{value}:#{key}; " # Note variables substituted into string
end # Prints "1:one; 2:two; 3:three; 
Run Code Online (Sandbox Code Playgroud)

each作为参数传递的函数key,value是传递给此函数的参数.你命名它们并不重要,第一个参数预期是关键,第二个参数预期.

让我们进行一些类比.考虑一个基本功能:

 def name_of_function(arg1, arg1)
   # Do stuff
 end

 # You'd call it such:
 foo.name_of_function bar, baz # bar is becomes as arg1,  baz becomes arg2 

 # As a block:

 ooga = lambda { |arg1, arg2|
   # Do stuff
 }

 # Note that this is exactly same as:

 ooga = lambda do |arg1, arg2|
   # Do stuff
 end

 # You would call it such:

 ooga.call(bar, baz) # bar is becomes as arg1,  baz becomes arg2
Run Code Online (Sandbox Code Playgroud)

所以你的代码也可以写成:

print_key_value = lambda{|arg1, arg2| print "#{arg1}:#{arg2}"}
h = { 
  :one => 1,
  :two => 2
}

h.each &print_key_value
Run Code Online (Sandbox Code Playgroud)

可以通过多种方式执行块内的代码:

  yield
  yield key, value # This is one possible way in which Hash#each can use a block
  yield item

  block.call
  block.call(key, value) # This is another way in which Hash#each can use a block
  block.call(item)
Run Code Online (Sandbox Code Playgroud)