Могу ли я определить смещение индекса в итераторе цикла each_with_index? Моя прямая попытка не удалась:
some_array.each_with_index{|item, index = 1| some_func(item, index) }
Редактировать:
Уточнение: мне не нужно смещение массива. Я хочу, чтобы индекс в each_with_index начинался не с 0, а, например, с 1.
Ответы:
Фактически,
Enumerator#with_index
получает смещение как необязательный параметр:[:foo, :bar, :baz].to_enum.with_index(1).each do |elem, i| puts "#{i}: #{elem}" end
выходы:
1: foo 2: bar 3: baz
Кстати, думаю, что только в 1.9.2.
источник
with_index
параметров, индексов из0
Ниже приводится краткое описание с использованием класса Ruby Enumerator.
[:foo, :bar, :baz].each.with_index(1) do |elem, i| puts "#{i}: #{elem}" end
вывод
1: foo 2: bar 3: baz
Каждый массив # возвращает перечислитель, а вызов Enumerator # with_index возвращает другой перечислитель, которому передается блок.
источник
1) Проще всего
index+1
вместоindex
функции подставить :some_array.each_with_index{|item, index| some_func(item, index+1)}
но, вероятно, это не то, что вам нужно.
2) Следующее, что вы можете сделать, это определить другой индекс
j
в блоке и использовать его вместо исходного индекса:some_array.each_with_index{|item, i| j = i + 1; some_func(item, j)}
3) Если вы хотите часто использовать индекс таким образом, определите другой метод:
module Enumerable def each_with_index_from_one *args, &pr each_with_index(*args){|obj, i| pr.call(obj, i+1)} end end %w(one two three).each_with_index_from_one{|w, i| puts "#{i}. #{w}"} # => 1. one 2. two 3. three
Обновить
Этот ответ, на который был дан ответ несколько лет назад, теперь устарел. Для современных Рубинов ответ Зака Сю будет работать лучше.
источник
+1
в моем коде на+2
или+10
. Это тоже работает.Если
some_index
это имеет какое-то значение, рассмотрите возможность использования хеша, а не массива.источник
Я столкнулся с этим.
Мое решение не является лучшим, но оно сработало для меня.
В итерации просмотра:
просто добавьте: index + 1
На этом все для меня, поскольку я не использую никаких ссылок на эти номера индексов, а просто для отображения в списке.
источник
Да, ты можешь
some_array[offset..-1].each_with_index{|item, index| some_func(item, index) } some_array[offset..-1].each_with_index{|item, index| some_func(item, index+offset) } some_array[offset..-1].each_with_index{|item, index| index+=offset; some_func(item, index) }
UPD
Также я должен заметить, что если смещение больше, чем размер вашего массива, это произойдет с ошибкой. Потому как:
some_array[1000,-1] => nil nil.each_with_index => Error 'undefined method `each_with_index' for nil:NilClass'
Что мы можем здесь сделать:
(some_array[offset..-1]||[]).each_with_index{|item, index| some_func(item, index) }
Или для предварительной проверки смещения:
offset = 1000 some_array[offset..-1].each_with_index{|item, index| some_func(item, index) } if offset <= some_array.size
Это немного взломано
UPD 2
Насколько вы обновили свой вопрос, и теперь вам нужно не смещение массива, а смещение индекса, поэтому решение @sawa будет отлично работать для вас
источник
Ариэль права. Это лучший способ справиться с этим, и это не так уж плохо
ary.each_with_index do |a, i| puts i + 1 #other code end
Это вполне приемлемо и лучше, чем большинство решений, которые я видел для этого. Я всегда думал, что это то, для чего нужен #inject ... да ладно.
источник
Другой подход - использовать
map
some_array = [:foo, :bar, :baz] some_array_plus_offset_index = some_array.each_with_index.map {|item, i| [item, i + 1]} some_array_plus_offset_index.each{|item, offset_index| some_func(item, offset_index) }
источник
Это работает в любой версии Ruby:
%W(one two three).zip(1..3).each do |value, index| puts value, index end
И для общего массива:
a.zip(1..a.length.each do |value, index| puts value, index end
источник
offset = 2 some_array[offset..-1].each_with_index{|item, index| some_func(item, index+offset) }
источник