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

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

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)?
}

person Upgradingdave    schedule 18.01.2010    source источник
comment
Анон: Нет, хеши не сортируются.   -  person Mikael S    schedule 18.01.2010
comment
хэши технически не сортируются, но в ruby ​​вы можете сортировать их в некотором смысле. sort() преобразует их в отсортированный вложенный массив, который затем можно преобразовать обратно в хеш: your_hash.sort.to_h   -  person jlesse    schedule 04.04.2018


Ответы (2)


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

hash.each_with_index { |(key,value),index| ... }
person YOU    schedule 18.01.2010
comment
конкретно: hash.each_with_index { |(key,value),index| ... } - person rampion; 18.01.2010
comment
круглые скобки необходимы, потому что hash.each дает каждую пару ключ-значение в Array. Скобки делают то же самое, что и (key,value) = arr, помещая первое значение (ключ) в key, а второе — в value. - person rampion; 18.01.2010
comment
Спасибо @S.Mark, @rampion, это сработало. Я не видел each_with_index в списке RDoc для Hash: ruby-doc.org/core /classes/Hash.html. Теперь я вижу, что это член Enumerable. Но очень плохо, что RDoc не может перекрестно ссылаться на each_with_index из Hash.html. - person Upgradingdave; 18.01.2010
comment
@Dave_Paroulek Я часто хотел того же. Я обнаружил, что проверка родительских модулей вручную является необходимым шагом при использовании vi для проверки методов классов. Часто я просто пропускаю irb и использую ClassName#instance_methods, чтобы убедиться, что ничего не пропустил. - person rampion; 20.01.2010
comment
Спасибо, @rampion, ClassName#instance_methods был очень полезен - person Upgradingdave; 25.01.2010

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

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

EDIT: согласно комментарию рампиона, я также только что узнал, что вы можете получить как ключ, так и значение в виде кортежа, если вы перебираете 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
person Kaleb Brasee    schedule 18.01.2010
comment
Проголосовали за доступ к итерированной коллекции изнутри цикла и ошибочный код: key в первом цикле представляет собой массив пары ключ+значение, поэтому использовать его в качестве индекса в hash неправильно. Вы когда-нибудь проверяли это? - person SasQ; 23.08.2013