[ruby] 루비에서 “역 범위”를 반복 할 수없는 이유가 있습니까?

Range를 사용하여 뒤로 반복하려고 시도했습니다 each.

(4..0).each do |i|
  puts i
end
==> 4..0

반복 0..4은 숫자 를 씁니다. 다른 범위에서는 괜찮은 r = 4..0것 같습니다 r.first == 4,, r.last == 0.

위의 구조가 예상 한 결과를 생성하지 않는 것이 이상하게 보입니다. 그 이유는 무엇입니까? 이 행동이 합리적 일 때 어떤 상황이 발생합니까?



답변

범위는 내용이 아니라 시작과 끝으로 정의되는 것입니다. 범위에 대한 “반복”은 일반적인 경우에 실제로 의미가 없습니다. 예를 들어, 두 날짜에 의해 생성 된 범위에서 “반복”하는 방법을 고려하십시오. 매일 반복 하시겠습니까? 월별? 연도 별? 주 단위로? 잘 정의되어 있지 않습니다. IMO, 순방향 범위에 허용된다는 사실은 편의 방법으로 만보아야합니다.

이와 같은 범위에서 역방향으로 반복하려면 항상 다음을 사용할 수 있습니다 downto.

$ r = 10..6
=> 10..6

$ (r.first).downto(r.last).each { |i| puts i }
10
9
8
7
6

여기에 더 많은 생각이 있습니다반복을 허용하고 역방향 범위를 일관되게 처리하는 것이 왜 어려운지에 다른 사람들의 있습니다.


답변

방법에 대해 (0..1).reverse_each어느 범위의 뒤쪽을 반복 할?


답변

Ruby에서 범위를 반복하면 범위 의 첫 번째 개체에 대한 메서드 가 each호출 succ됩니다.

$ 4.succ
=> 5

그리고 5는 범위 밖에 있습니다.

이 해킹으로 역 반복을 시뮬레이션 할 수 있습니다.

(-4..0).each { |n| puts n.abs }

John은 이것이 0에 걸치면 작동하지 않을 것이라고 지적했습니다.

>> (-2..2).each { |n| puts -n }
2
1
0
-1
-2
=> -2..2

그들이 의도를 모호하게하기 때문에 내가 그들 중 어떤 것도 정말 좋아한다고 말할 수 없습니다.


답변

“Programming Ruby”라는 책에 따르면 Range 개체는 범위의 두 끝점을 저장하고 .succ멤버를 사용하여 중간 값을 생성합니다. 범위에서 사용하는 데이터 유형의 종류에 따라 언제든지 멤버 의 하위 클래스를 Integer만들고 다시 정의하여 .succ역방향 반복자처럼 작동하도록 할 수 있습니다..next ).

Range를 사용하지 않고도 원하는 결과를 얻을 수 있습니다. 이 시도:

4.step(0, -1) do |i|
    puts i
end

이것은 -1 단계에서 4에서 0으로 이동합니다. 그러나 Integer 인수를 제외하고 이것이 작동하는지 여부는 알 수 없습니다.


답변

또 다른 방법은 (1..10).to_a.reverse


답변

for루프를 사용할 수도 있습니다 .

for n in 4.downto(0) do
  print n
end

인쇄 :

4
3
2
1
0


답변

목록이 그렇게 크지 않은 경우. [*0..4].reverse.each { |i| puts i }
가장 간단한 방법 이라고 생각
합니다.