Enumerable로 더 정교해지기
12649 단어 ruby
열거 가능이란 무엇입니까?
The Enumerable mixin provides collection classes with several traversals and searching methods, and with the ability to sort. The class must provide a method each, which yields successive members of the collection.
https://ruby-doc.org/core-2.7.1/Enumerable.html
간단히 말해서 Array, Hash, String과 같은 각각의 메소드를 가지는 클래스는 Enumerable 메소드를 가지고 있습니다.
각각을 사용하는 코드 찾기, Enumerable 메서드 사용 고려
each
를 사용하는 코드가 보이면 잠재적으로 사용하지 않고 프로시저를 다시 작성할 수 있습니다. 코드베이스의 일부를 생각한다면 그것을 찾아보십시오.
또한 적절한 Enumerable 메서드를 사용하면 코드가 정교해집니다. 내가 본 정확한 예를 보고 배워봅시다.
사용 사례
사례 1: 선택
전에
arr = [1, 2, 3, 4, 5]
new_arr = []
arr.each do |v|
new_arr << v if v.odd?
end
p new_arr # => [1, 3, 5]
후에
new_arr = arr.select(&:odd?)
p new_arr # => [1, 3, 5]
사례 2: 지도
전에
arr = [1, 2, 3, 4, 5]
new_arr = []
arr.each do |v|
new_arr << v * 2
end
p new_arr # => [2, 4, 6, 8, 10]
후에
new_arr = arr.map { |v| v * 2 }
p new_arr # => [2, 4, 6, 8, 10]
사례 3: 주입
전에
arr = [1, 2, 3, 4, 5]
sum = 0
arr.each do |v|
sum += v
end
p sum # => 15
후에
arr = [1, 2, 3, 4, 5]
sum = arr.inject(:+)
p sum # => 15
사례 4: 있습니까?
전제 조건
booking_statuses는 아래와 같이 정의되며 상태 전환을 확인하려고 합니다.
booking_statuses = {
pending: 0,
payment_requested: 1,
paid: 2,
cancelled: 3
}
전에
def validate_booking_transition(passed_status)
if passed_status == booking_statuses[:cancelled]
allowed = [
booking_statuses[:pending],
booking_statuses[:payment_requested],
booking_statuses[:paid]
].include?(passed_status)
elsif ...
.
.
.
end
후에
def validate_booking_transition(passed_status)
if passed_status == booking_statuses[:cancelled]
allowed = %i(pending payment_requested paid).any? do |v|
passed_status == booking_statuses[v]
end
elsif ...
.
.
.
end
사례 5: group_by
전에
arr = [{code: 'a', val: 1}, {code: 'a', val: 2}, {code: 'b', val: 3}, {code: 'b', val: 4}]
new_hash = {}
arr.each do |hash|
k = hash[:code]
new_hash[k] = [] if new_hash[k].nil?
new_hash[k] << hash[:val]
end
p new_hash #=> {"a"=>[1, 2], "b"=>[3, 4]}
후에
new_hash = arr.group_by { |h| h[:code] }.transform_values { |grouped_arr| grouped_arr.map { |h| h[:val] } }
p new_hash #=> {"a"=>[1, 2], "b"=>[3, 4]}
고려 사항
각 사용 사례를 살펴보십시오. Case 1-3은 일반적인 Enumerable 메소드 소개입니다.
사례 4는 적절한 Enumerable 메서드를 사용하여 우리가 의도한 것을 표현할 수 있음을 보여줍니다.
그렇다면 사례 5에 대해 무엇을 말할 수 있습니까? 예전보다 더 똑똑해 보이죠? 아니면 더 복잡해졌습니까?
각 경우에 대해 자세히 알아보겠습니다.
루프에서,
The Enumerable mixin provides collection classes with several traversals and searching methods, and with the ability to sort. The class must provide a method each, which yields successive members of the collection.
each
를 사용하는 코드가 보이면 잠재적으로 사용하지 않고 프로시저를 다시 작성할 수 있습니다. 코드베이스의 일부를 생각한다면 그것을 찾아보십시오.또한 적절한 Enumerable 메서드를 사용하면 코드가 정교해집니다. 내가 본 정확한 예를 보고 배워봅시다.
사용 사례
사례 1: 선택
전에
arr = [1, 2, 3, 4, 5]
new_arr = []
arr.each do |v|
new_arr << v if v.odd?
end
p new_arr # => [1, 3, 5]
후에
new_arr = arr.select(&:odd?)
p new_arr # => [1, 3, 5]
사례 2: 지도
전에
arr = [1, 2, 3, 4, 5]
new_arr = []
arr.each do |v|
new_arr << v * 2
end
p new_arr # => [2, 4, 6, 8, 10]
후에
new_arr = arr.map { |v| v * 2 }
p new_arr # => [2, 4, 6, 8, 10]
사례 3: 주입
전에
arr = [1, 2, 3, 4, 5]
sum = 0
arr.each do |v|
sum += v
end
p sum # => 15
후에
arr = [1, 2, 3, 4, 5]
sum = arr.inject(:+)
p sum # => 15
사례 4: 있습니까?
전제 조건
booking_statuses는 아래와 같이 정의되며 상태 전환을 확인하려고 합니다.
booking_statuses = {
pending: 0,
payment_requested: 1,
paid: 2,
cancelled: 3
}
전에
def validate_booking_transition(passed_status)
if passed_status == booking_statuses[:cancelled]
allowed = [
booking_statuses[:pending],
booking_statuses[:payment_requested],
booking_statuses[:paid]
].include?(passed_status)
elsif ...
.
.
.
end
후에
def validate_booking_transition(passed_status)
if passed_status == booking_statuses[:cancelled]
allowed = %i(pending payment_requested paid).any? do |v|
passed_status == booking_statuses[v]
end
elsif ...
.
.
.
end
사례 5: group_by
전에
arr = [{code: 'a', val: 1}, {code: 'a', val: 2}, {code: 'b', val: 3}, {code: 'b', val: 4}]
new_hash = {}
arr.each do |hash|
k = hash[:code]
new_hash[k] = [] if new_hash[k].nil?
new_hash[k] << hash[:val]
end
p new_hash #=> {"a"=>[1, 2], "b"=>[3, 4]}
후에
new_hash = arr.group_by { |h| h[:code] }.transform_values { |grouped_arr| grouped_arr.map { |h| h[:val] } }
p new_hash #=> {"a"=>[1, 2], "b"=>[3, 4]}
고려 사항
각 사용 사례를 살펴보십시오. Case 1-3은 일반적인 Enumerable 메소드 소개입니다.
사례 4는 적절한 Enumerable 메서드를 사용하여 우리가 의도한 것을 표현할 수 있음을 보여줍니다.
그렇다면 사례 5에 대해 무엇을 말할 수 있습니까? 예전보다 더 똑똑해 보이죠? 아니면 더 복잡해졌습니까?
각 경우에 대해 자세히 알아보겠습니다.
루프에서,
arr = [1, 2, 3, 4, 5]
new_arr = []
arr.each do |v|
new_arr << v if v.odd?
end
p new_arr # => [1, 3, 5]
new_arr = arr.select(&:odd?)
p new_arr # => [1, 3, 5]
arr = [1, 2, 3, 4, 5]
new_arr = []
arr.each do |v|
new_arr << v * 2
end
p new_arr # => [2, 4, 6, 8, 10]
new_arr = arr.map { |v| v * 2 }
p new_arr # => [2, 4, 6, 8, 10]
arr = [1, 2, 3, 4, 5]
sum = 0
arr.each do |v|
sum += v
end
p sum # => 15
arr = [1, 2, 3, 4, 5]
sum = arr.inject(:+)
p sum # => 15
booking_statuses = {
pending: 0,
payment_requested: 1,
paid: 2,
cancelled: 3
}
def validate_booking_transition(passed_status)
if passed_status == booking_statuses[:cancelled]
allowed = [
booking_statuses[:pending],
booking_statuses[:payment_requested],
booking_statuses[:paid]
].include?(passed_status)
elsif ...
.
.
.
end
def validate_booking_transition(passed_status)
if passed_status == booking_statuses[:cancelled]
allowed = %i(pending payment_requested paid).any? do |v|
passed_status == booking_statuses[v]
end
elsif ...
.
.
.
end
arr = [{code: 'a', val: 1}, {code: 'a', val: 2}, {code: 'b', val: 3}, {code: 'b', val: 4}]
new_hash = {}
arr.each do |hash|
k = hash[:code]
new_hash[k] = [] if new_hash[k].nil?
new_hash[k] << hash[:val]
end
p new_hash #=> {"a"=>[1, 2], "b"=>[3, 4]}
new_hash = arr.group_by { |h| h[:code] }.transform_values { |grouped_arr| grouped_arr.map { |h| h[:val] } }
p new_hash #=> {"a"=>[1, 2], "b"=>[3, 4]}
각 사용 사례를 살펴보십시오. Case 1-3은 일반적인 Enumerable 메소드 소개입니다.
사례 4는 적절한 Enumerable 메서드를 사용하여 우리가 의도한 것을 표현할 수 있음을 보여줍니다.
그렇다면 사례 5에 대해 무엇을 말할 수 있습니까? 예전보다 더 똑똑해 보이죠? 아니면 더 복잡해졌습니까?
각 경우에 대해 자세히 알아보겠습니다.
루프에서,
그것으로부터 우리는 그들이 루프 내에서 1 절차를 진행한다고 말할 수 있습니다.
Case 5의 다른 점은 iteration 내에서 여러 절차를 수행한다는 것입니다.
그들은
code
를 키로 사용하는 해시 생성val
생성또한
map
메서드 내에서 transform_values
를 실행합니다. 상황을 더 악화시켰습니다. 예, 계산 순서 측면에서 단일 루프에서 이중 루프를 생성합니다.즉, 단일 반복 내에서 여러 절차를 처리해야 하는 경우
each
계산 순서와 가독성 측면 모두에서 주도권을 가질 수 있습니다.Enumerable 메서드 사용의 장점을 다시 생각하십시오.
each
보다 적절한 Enumerable 메서드를 사용하여 의도를 보다 명확하게 설명할 수 있습니다.
그리고 많은 경우에 가독성과 유지관리가 가장 중요한 정책입니다. 왜 그것을 사용하지 않습니까?
그리고 함수형 프로그래밍에 익숙하지 않다면 부작용에 대해 생각해 볼 수 있는 좋은 기회가 될 수도 있습니다.
그러나 사례 5에서 보여주듯이 각각이 결국 최고의 접근 방식이 될 수 있습니다. 리팩토링을 통해 중첩된 반복을 생성하지 않도록 하십시오.
결론
Enumerable은 프로그래밍을 재미있게 만듭니다. 즐기다!
In Japanese
Reference
이 문제에 관하여(Enumerable로 더 정교해지기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/kazu9su/be-more-sophisticated-with-enumerable-45h7
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Enumerable은 프로그래밍을 재미있게 만듭니다. 즐기다!
In Japanese
Reference
이 문제에 관하여(Enumerable로 더 정교해지기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/kazu9su/be-more-sophisticated-with-enumerable-45h7텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)