Можно ли получить доступ к индексу в каждом цикле хеширования?

119

Вероятно, мне не хватает чего-то очевидного, но есть ли способ получить доступ к индексу / счетчику итерации внутри хеша каждого цикла?

hash = {'three' => 'one', 'four' => 'two', 'one' => 'three'}
hash.each { |key, value| 
    # any way to know which iteration this is
    #   (without having to create a count variable)?
}
Upgradingdave
источник
3
Анон: Нет, хеши не сортируются.
Mikael S
хеши технически не отсортированы, но в Ruby их можно отсортировать в определенном смысле. sort () преобразует их в отсортированный вложенный массив, который затем можно преобразовать обратно в хэш: your_hash.sort.to_h
jlesse 03

Ответы:

296

Если вы хотите знать индекс каждой итерации, вы можете использовать .each_with_index

hash.each_with_index { |(key,value),index| ... }
ТЫ
источник
24
в частности:hash.each_with_index { |(key,value),index| ... }
rampion
22
hash.eachпарные скобки необходимы b / c дает каждую пару "ключ-значение" в файле Array. Парены делают то же самое (key,value) = arr, что и первое значение (ключ) key, а второе - в value.
rampion
1
Спасибо @ S.Mark, @rampion, это сработало. Я не видел each_with_indexперечисленных в RDoc для хеша: ruby-doc.org/core/classes/Hash.html . Теперь я вижу, что это член Enumerable. Но очень плохо, что RDoc не может ссылаться на each_with_indexHash.html.
Upgradingdave
2
@Dave_Paroulek Я часто желал того же. Я обнаружил, что проверка родительских модулей вручную является необходимым шагом при использовании vi для проверки методов классов. Часто я просто перехожу irbи использую, ClassName#instance_methodsчтобы убедиться, что я ничего не пропустил.
rampion
Спасибо, @rampion, мне ClassName#instance_methodsочень помогли
Upgradingdave
11

Вы можете перебирать ключи и получать значения вручную:

hash.keys.each_with_index do |key, index|
   value = hash[key]
   print "key: #{key}, value: #{value}, index: #{index}\n"
   # use key, value and index as desired
end

РЕДАКТИРОВАТЬ: за комментарий rampion, я также только что узнал, что вы можете получить как ключ, так и значение в виде кортежа, если вы выполните итерацию hash:

hash.each_with_index do |(key, value), index|
   print "key: #{key}, value: #{value}, index: #{index}\n"
   # use key, value and index as desired
end
Калеб Браси
источник
Проголосовали за доступ к повторяющейся коллекции изнутри цикла и ошибочный код: keyв первом цикле находится массив пары ключ + значение, поэтому использование его в качестве индекса hashневерно. Вы когда-нибудь это тестировали?
SasQ