我很容易感到與迭代混淆 - 任何人都可以通過這個代碼做什麼? 朋友和家人都是哈希,語言是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}" }
{a: => :b, :c => :d}
被強制轉換爲陣列[[:a, :b], [:c, :d]]
時each
被調用。each
上的塊取一個變量x
,則傳遞它的每個元素,即第一次迭代時爲[:a, :b]
,下一次爲[:c, :d]
。each
上的塊取兩個變量x
和y
,則將每個元素如[:a, :b]
與變量進行匹配。對於第一次迭代,x
變成:a
並且y
變成:b
。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是開源的,你可以看到究竟是如何Array#each和Hash#each在C,一般匹配平原實現上面的Ruby代碼。
你確定'friends'是一個散列而不是一個數組嗎? –