我很容易对迭代感到困惑 - 谁能告诉我这段代码到底做了什么?朋友和家人是哈希,语言是 Ruby。
friends.each { |x| puts "#{x}" }
family.each { |x, y| puts "#{x}: #{y}" }
我很容易对迭代感到困惑 - 谁能告诉我这段代码到底做了什么?朋友和家人是哈希,语言是 Ruby。
friends.each { |x| puts "#{x}" }
family.each { |x, y| puts "#{x}: #{y}" }
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"]
所以,sayArray#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 是开源的,您可以确切地看到Array#each和Hash#each是如何在 C 中实现的,这通常与上面的纯 Ruby 代码相匹配。
{a: => :b, :c => :d}
转换为数组。[[:a, :b], [:c, :d]]
each
each
接受一个 variable x
,则传递它的每个元素,这是[:a, :b]
第一次迭代,[:c, :d]
下一次迭代。each
接受两个变量x
和y
,则每个元素[:a, :b]
都与变量匹配。对于第一次迭代,x
变得:a
和y
变得:b
。