Множественное назначение переменной с помощью each_with_index

У меня есть этот фрагмент кода, ведро в этом случае - это просто массив в более крупном массиве:

def Dict.get_slot(aDict, key, default=nil)
 # Returns the index, key, and value of a slot found in a bucket.
 bucket = Dict.get_bucket(aDict, key)

 bucket.each_with_index do |kv, i|
 k, v = kv
 if key == k
 return i, k, v
 end
 end

 return -1, key, default
end

Две переменные, называемые k и v, устанавливаются в contens of kv. Но как это может работать, когда kv содержит только одно значение за раз?

Я написал это в другой файл:

bucket = ['key', 'value']
 key = 'key'
 bucket.each_with_index do |kv, i|
 k, v = kv
 if key == k
 puts k, v, i
 end
 end

И тогда переменная v была пустой:

key

0

Мой вопрос: почему в первом примере работает несколько заданий, но не во втором?

2 ответа

bucket - словарь, просто поместите: список пар значений, а не только список значений. Рассматривать:

bucket.each do |kv|
 # kv is an array: [some_k, some_v]
 k, v = kv
 # k is some_k
 # v is some_v
end

bucket.each_with_index do |kv, i|
 # kv is again an array: [some_k, some_v]
 k, v = kv
 # k is some_k
 # v is some_v
end

В качестве побочного примечания этот тип "сопоставления с образцом" также может быть использован в вложенной форме для параметров блока напрямую:

bucket.each_with_index do |(k, v), i|
 # k is some_k
 # v is some_v
end


Когда вы вызываете bucket.each_with_index он сначала действует на "ключ", затем "значение",

Вы можете попробовать вложенные массивы, поэтому в этом примере каждый член массива представляет собой массив с двумя элементами.

irb(main):012:0> [['a','b'],['c','d']].each_with_index{|x,i|puts "#{i}: #{x}"}
0: ["a", "b"]
1: ["c", "d"]

Затем вы можете определить их по индексу

irb(main):019:0> [['a','b'],['c','d']].each_with_index{|x,i|puts "#{i}: #{x[0]} - #{x[1]}"}
0: a - b
1: c - d

Или установите их как значения с использованием синтаксиса, который вы использовали:

irb(main):020:0> [['a','b'],['c','d']].each_with_index{|x,i| a,b = x ; puts "#{i}: #{a} - #{b}"}
0: a - b
1: c - d

Без одного лайнера:

bucket = [
 ['a','b'],
 ['c','d']
]
bucket.each_with_index do |x, index|
 k, v = x
 puts index
 puts "#{k} = #{v}"
end

licensed under cc by-sa 3.0 with attribution.