Enumerator와 Enumerator:Lazy의 차이
7401 단어 Ruby
개시하다
Ruby2.0은 Enumerable#lazy
방법과 반환 값Enumerator::Lazy
을 가져왔다.
이 글은 Enumerable#lazy
과 Enumerator::Lazy
가 무한 목록의 맵을 소개했다.
또 설명Enumerator
과 Enumerator::Lazy
의 본질적 차이도 설명했다.
지연 목록
지연 목록은 Haskell 등 일부 함수형 언어에서 자주 사용하는 것이다
지연평가란 값이 필요하기 전에 계산하지 않으면 무한 연장된 목록을 처리할 수 있다는 것이다.
무한 목록 추가
그냥 해보면 안 돼요.
다음은 무한 목록Range
의 표현식[1]이다.
이 공식의 집행은 끝나지 않는다.
무한 목록 맵을 실행하면 끝나지 않습니다[1] pry(main)> (1..Float::INFINITY).map{|n| n*2}.first(5)
# => (実行が終わらない...)
[1]의 공식map
에서 map
라고 부른다.Enumerable#map
는 수조Enumerable#map
를 반환값으로 하는 방법이기 때문에 무한 길이의 수조를 만들어야 처리가 끝나지 않는다.
레이지 붙이면 움직여요.
사용Array
, 아래 방정식[2]과 같이 Enumerable#lazy
를 통해 무한 목록을 처리할 수 있다.
무한 목록은 Enumerable#lazy에서 처리할 수 있습니다.[2] pry(main)> (1..Float::INFINITY).lazy.map{|n| n*2}.first(5)
# => [2, 4, 6, 8, 10]
[2]의 공식map
에서 map
라고 부른다.Enumerator::Lazy#map
는 목록(Aray, Range 등)을 지연 목록Enumerable#lazy
으로 전환하는 방법이다.Enumerator::Lazy
도 되돌아오는 방법Enumerator::Lazy#map
이다.
따라서 Enumerator::Lazy
전체는(1..Float::INFINITY).lazy.map{|n| n*2}
이다.Enumerator::Lazy
의 내용은 호출Enumerator::Lazy
또는force(to_a)
이전에 수치를 평가하지 않는다.
마지막으로 first
라고 불렸을 때 드디어 수치를 평가해야 하기 때문에 무한 목록을 처리할 수 있다.
게임 이름: Lazy#map
여기서 주의해야 할 것은 [1]과[2]의Enumerator::Lazy#first
는 완전히 다른 방법으로 정의된 장소와 반환값이 모두 다르다는 것이다.
특히 [2]에서는 결과를 바로 배열하지 않고 지연 목록으로 저장하는 것이 중요하다.
지연 목록은 Haskell 등 일부 함수형 언어에서 자주 사용하는 것이다
지연평가란 값이 필요하기 전에 계산하지 않으면 무한 연장된 목록을 처리할 수 있다는 것이다.
무한 목록 추가
그냥 해보면 안 돼요.
다음은 무한 목록Range
의 표현식[1]이다.
이 공식의 집행은 끝나지 않는다.
무한 목록 맵을 실행하면 끝나지 않습니다[1] pry(main)> (1..Float::INFINITY).map{|n| n*2}.first(5)
# => (実行が終わらない...)
[1]의 공식map
에서 map
라고 부른다.Enumerable#map
는 수조Enumerable#map
를 반환값으로 하는 방법이기 때문에 무한 길이의 수조를 만들어야 처리가 끝나지 않는다.
레이지 붙이면 움직여요.
사용Array
, 아래 방정식[2]과 같이 Enumerable#lazy
를 통해 무한 목록을 처리할 수 있다.
무한 목록은 Enumerable#lazy에서 처리할 수 있습니다.[2] pry(main)> (1..Float::INFINITY).lazy.map{|n| n*2}.first(5)
# => [2, 4, 6, 8, 10]
[2]의 공식map
에서 map
라고 부른다.Enumerator::Lazy#map
는 목록(Aray, Range 등)을 지연 목록Enumerable#lazy
으로 전환하는 방법이다.Enumerator::Lazy
도 되돌아오는 방법Enumerator::Lazy#map
이다.
따라서 Enumerator::Lazy
전체는(1..Float::INFINITY).lazy.map{|n| n*2}
이다.Enumerator::Lazy
의 내용은 호출Enumerator::Lazy
또는force(to_a)
이전에 수치를 평가하지 않는다.
마지막으로 first
라고 불렸을 때 드디어 수치를 평가해야 하기 때문에 무한 목록을 처리할 수 있다.
게임 이름: Lazy#map
여기서 주의해야 할 것은 [1]과[2]의Enumerator::Lazy#first
는 완전히 다른 방법으로 정의된 장소와 반환값이 모두 다르다는 것이다.
특히 [2]에서는 결과를 바로 배열하지 않고 지연 목록으로 저장하는 것이 중요하다.
[1] pry(main)> (1..Float::INFINITY).map{|n| n*2}.first(5)
# => (実行が終わらない...)
[2] pry(main)> (1..Float::INFINITY).lazy.map{|n| n*2}.first(5)
# => [2, 4, 6, 8, 10]
map
->Enumerable#map
Array
->Enumerator::Lazy#map
지연 시간 목록
Ruby2.0부터 새로운 지연 명단이 나왔다고 오해할 수 있지만 이전부터 루비Enumerator::Lazy
반이 있었다.
예를 들어 Enumerator
블록을 생략하면 순서대로 IO#each_line
파일의 행별로 yield
반환됩니다.
다음 예에서는 전체 파일을 읽지 않고 처음 열 줄만 처리할 수 있습니다.
IO#each_line에서 모든 파일을 읽지 않습니다.File.open("log.txt") do |f|
puts f.each_line.first(10)
end
놀랍게도 Enumerator
와 Enumerator::Lazy
는 모두 지연 목록이었다.
조금만 신경 쓰면Enumerator
무한 리스트를 처리할 수도 있다.이것은 첫 번째 예의 결과와 완전히 같다.
Enumerator는 무한 목록을 처리할 수도 있습니다.Enumerator.new{|y|
(1..Float::INFINITY).each{|n|
y << n*2
}
}.first(5) # => [2, 4, 6, 8, 10]
이렇게 해서 Enumerator
무한 목록을 처리할 수도 있지만 Enumerator
를 사용하면
맵을 통해 직관적이고 읽기 쉬운 짧은 코드로 표현할 수 있다.
란즈의 진정한 목적 Enumerator::Lazy
와 Enumerator::Lazy
두 종류의 본질적인 차이는 다음과 같다.
방법체인에서 호출Enumerator
이 되돌아오는지map
또는 되돌아오는지Array
.
두 학급 자체의 기능은 거의 차이가 없다.
다시 말하면 Enumerator::Lazy
의 진정한 목적은 레이지판Enumerator::Lazy
과 map
를 새롭게 정의하는 것이다.
lazy를 더하면 맵의 동작이 변하는 불가사의한 방법
왜, lazy를 더하면 맵과 select의 동작이 달라질까요?이런 의문이 생기는 사람도 있을 거라고 생각합니다.
Enumerable#lazy를 제작한 Yutaka HARA씨가 알탄라고 대답했다.
File.open("log.txt") do |f|
puts f.each_line.first(10)
end
Enumerator.new{|y|
(1..Float::INFINITY).each{|n|
y << n*2
}
}.first(5) # => [2, 4, 6, 8, 10]
Enumerator::Lazy
와 Enumerator::Lazy
두 종류의 본질적인 차이는 다음과 같다.방법체인에서 호출
Enumerator
이 되돌아오는지map
또는 되돌아오는지Array
.두 학급 자체의 기능은 거의 차이가 없다.
다시 말하면
Enumerator::Lazy
의 진정한 목적은 레이지판Enumerator::Lazy
과 map
를 새롭게 정의하는 것이다.lazy를 더하면 맵의 동작이 변하는 불가사의한 방법
왜, lazy를 더하면 맵과 select의 동작이 달라질까요?이런 의문이 생기는 사람도 있을 거라고 생각합니다.
Enumerable#lazy를 제작한 Yutaka HARA씨가 알탄라고 대답했다.
select
모듈에서 레이지 버전을 원하는 방법Enumerable
,map
,select
,reject
,drop
,...많이요.Enumerable
모듈의 방법이 너무 많아집니다.Enumerator::Lazy
명명 공간을 제공함으로써'lazy'의 방법 이름만 추가하면 lazy판map
과 select
등을 사용할 수 있다.Enumerable#lazy
"map
과select
등lazy판의 명명 공간을 제공하는 방법"을 설명한 것이 더 정확한 설명이다.총결산
Enumerator::Lazy
와Enumerator
의 본질적 차이점map
과select
등 방법의 행위가 다르다Enumerator::Lazy
의 진정한 목적은 레이지 버전의 map
과 select
보태다
학급 계승 관계
Enumerator::Lazy
,Enumerator
,Enumerable
등의 계승 관계가 복잡하기 때문에 그림으로 정리했다.
딜레이 리스트를 사용할 수 있는 장면입니다.
마지막으로 나는 지연 목록을 효과적으로 사용할 수 있는 장면을 생각했다.
map
와 first
방법을 사용하면 수열의 길이를 의식하지 않고 각 처리를 추상화할 수 있다.나는 블로그를 쓰고 있다.
블로그에도 같은 내용의 기사를 썼다.
Reference
이 문제에 관하여(Enumerator와 Enumerator:Lazy의 차이), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/gam0022/items/8acfc0c674b96060c03f텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)