我很容易对迭代感到困惑 - 任何人都可以告诉我这段代码的确切内容吗? 朋友和家人都是哈希,语言是Ruby。
friends.each { |x| puts "#{x}" }
family.each { |x, y| puts "#{x}: #{y}" }
答案 0 :(得分:4)
friends.each { |x| puts "#{x}" }
family.each { |x, y| puts "#{x}: #{y}" }
第一个基本上相当于:
x = [friends.keys[0], friends.values[0]]
puts "#{x}"
x = [friends.keys[1], friends.values[1]]
puts "#{x}"
x = [friends.keys[2], friends.values[2]]
puts "#{x}"
# ...
x = [friends.keys[n], friends.values[n]]
puts "#{x}"
第二个:
x = family.keys[0]
y = family.values[0]
puts "#{x}: #{y}"
x = family.keys[1]
y = family.values[1]
puts "#{x}: #{y}"
x = family.keys[2]
y = family.values[2]
puts "#{x}: #{y}"
# ...
x = family.keys[n]
y = family.values[n]
puts "#{x}: #{y}"
在方法之后,只要有{ |...| ... }
或do |...|; ...; end
之类的内容,就会创建所谓的块。该块传递给方法,该方法可以yield
到块的参数。 Array#each
将使用每个元素调用块; Hash#each
将通过[key, value]
。
当然,你可以做一些完全不同的事情,如下:
def test
yield('oh my')
yield('i really')
yield('like blocks')
end
test { |a| puts a }
哪个输出
oh my
i really
like blocks
如果yield
数组为一个数组,则可以将其分配给多个或单个参数。
def test
yield(['oh', 'my'])
yield(['i', 'really'])
yield(['like', 'blocks'])
end
test { |a, b| puts "#{a}-#{b}" }
哪个输出
oh-my
i-really
like-blocks
或者,如果您只接受块中的单个参数,它将作为数组传递
test { |a| puts a.inspect }
输出
["oh", "my"]
["i", "really"]
["like", "blocks"]
所以,说Array#each
不存在,你想自己创建它。你可以做点什么
class Array
def each
i = 0
while i < length_of_underlying_array
next_element = get_element(i)
yield(next_element)
end
end
end
或者,Hash#each
class Hash
def each
i = 0
while i < length_of_underlying_hash
next_key = keys[i]
next_value = values[i]
yield([next_key, next_value])
end
end
end
另一个一般提示,因为Ruby是开源的,你可以准确地看到在C中实现Array#each和Hash#each的方式,它通常与上面的普通Ruby代码相匹配。
答案 1 :(得分:3)
{a: => :b, :c => :d}
时,哈希值[[:a, :b], [:c, :d]]
会转换为数组each
。each
上的阻截获取一个变量x
,则会传递其中的每个元素,第一次迭代为[:a, :b]
,下一次为[:c, :d]
。 each
上的阻止了两个变量x
和y
,那么像[:a, :b]
这样的每个元素都会与变量匹配。对于第一次迭代,x
变为:a
,y
变为:b
。