Posso definir o deslocamento do índice no iterador de loop each_with_index? Minha tentativa direta falhou:
some_array.each_with_index{|item, index = 1| some_func(item, index) }
Editar:
Esclarecimento: Não quero um deslocamento de array. Quero que o índice dentro de each_with_index não comece em 0, mas, por exemplo, em 1
Respostas:
Na verdade,
Enumerator#with_index
recebe deslocamento como um parâmetro opcional:[:foo, :bar, :baz].to_enum.with_index(1).each do |elem, i| puts "#{i}: #{elem}" end
saídas:
1: foo 2: bar 3: baz
BTW, acho que só existe no 1.9.2.
fonte
with_index
sem parâmetros, índices de0
O seguinte é sucinto, usando a classe Enumerator do Ruby.
[:foo, :bar, :baz].each.with_index(1) do |elem, i| puts "#{i}: #{elem}" end
resultado
1: foo 2: bar 3: baz
Array # each retorna um enumerador e chamar Enumerator # with_index retorna outro enumerador, para o qual um bloco é passado.
fonte
1) O mais simples é substituir em
index+1
vez deindex
para a função:some_array.each_with_index{|item, index| some_func(item, index+1)}
mas provavelmente não é isso que você deseja.
2) A próxima coisa que você pode fazer é definir um índice diferente
j
dentro do bloco e usá-lo em vez do índice original:some_array.each_with_index{|item, i| j = i + 1; some_func(item, j)}
3) Se você deseja usar o índice dessa forma com frequência, defina outro método:
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
Atualizar
Essa resposta, que foi respondida há alguns anos, agora é obsoleta. Para Rubis modernos, a resposta de Zack Xu funcionará melhor.
fonte
+1
no meu código para+2
ou+10
. Funciona também.Se
some_index
for de alguma forma significativo, considere usar um hash, em vez de uma matriz.fonte
Eu corri para ele.
Minha solução desnecessária é a melhor, mas funcionou para mim.
Na iteração de visualização:
basta adicionar: índice + 1
Isso é tudo para mim, já que não uso nenhuma referência a esses números de índice, mas apenas para mostrar em uma lista.
fonte
Sim você pode
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
Também devo notar que se o deslocamento for maior do que o tamanho do seu Array, ocorrerá um erro. Porque:
some_array[1000,-1] => nil nil.each_with_index => Error 'undefined method `each_with_index' for nil:NilClass'
O que podemos fazer aqui:
(some_array[offset..-1]||[]).each_with_index{|item, index| some_func(item, index) }
Ou para pré-validar o deslocamento:
offset = 1000 some_array[offset..-1].each_with_index{|item, index| some_func(item, index) } if offset <= some_array.size
Isso é um pouco hacky
UPD 2
Até onde você atualizou sua pergunta e agora você não precisa do deslocamento de matriz, mas de deslocamento de índice, então a solução @sawa funcionará bem para você
fonte
Ariel está certa. Esta é a melhor maneira de lidar com isso, e não é tão ruim
ary.each_with_index do |a, i| puts i + 1 #other code end
Isso é perfeitamente aceitável e melhor do que a maioria das soluções que vi para isso. Sempre achei que #inject era para isso ... bem.
fonte
Outra abordagem é usar
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) }
fonte
Isso funciona em todas as versões do Ruby:
%W(one two three).zip(1..3).each do |value, index| puts value, index end
E para uma matriz genérica:
a.zip(1..a.length.each do |value, index| puts value, index end
fonte
offset = 2 some_array[offset..-1].each_with_index{|item, index| some_func(item, index+offset) }
fonte