program story

Ruby each_with_index 오프셋

inputbox 2020. 9. 24. 07:48
반응형

Ruby each_with_index 오프셋


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

BTW, 나는 1.9.2에만 있다고 생각합니다.


다음은 Ruby의 Enumerator 클래스를 사용하여 간결합니다.

[:foo, :bar, :baz].each.with_index(1) do |elem, i|
    puts "#{i}: #{elem}"
end

산출

1: foo
2: bar
3: baz

Array # each는 열거자를 반환하고 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


최신 정보

몇 년 전에 답변 된이 답변은 이제 구식입니다. 현대 루비의 경우 Zack Xu의 답변이 더 잘 작동합니다.


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

As far as you updated your question and now you need not Array offset, but index offset so @sawa solution will works fine for you


Ariel is right. This is the best way to handle this, and it's not that bad

ary.each_with_index do |a, i|
  puts i + 1
  #other code
end

That is perfectly acceptable, and better than most of the solutions I've seen for this. I always thought this was what #inject was for...oh well.


Another approach is to use 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) }

This works in every ruby version:

%W(one two three).zip(1..3).each do |value, index|
  puts value, index
end

And for a generic array:

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

참고URL : https://stackoverflow.com/questions/5646390/ruby-each-with-index-offset

반응형