.reduce: 다양한 배열 방법
오늘 저는 혼란을 없애고 다양한 방법의 몇 가지 예를 보여드리고자 합니다.
.reduce는 무엇을 합니까?
쉬운 예부터 시작하겠습니다. 단일 값으로 줄이려는 숫자 배열이 있다고 가정해 보겠습니다. (강력한 Ruby 기반 마법사가 .sum 메서드를 제거했다고 가정해 보겠습니다.)
array = [1, 1, 1]
array.reduce(0) {|sum, i| sum + i} #=> 3
확인. 위의 코드가 방금 수행한 작업을 풀어보겠습니다.
. 누산기 방법으로 축소
위에서 .reduce에 단일 매개변수(
reduce(0)
)와 파이프 내에서 명명된 두 변수( |sum, i|
)를 지정했습니다. 매개변수를 시작 값이라고 하고 두 변수를 각각 memo 및 current_element라고 합시다.array.reduce(start) {|memo, current_element| statement}
current_element는 매우 간단합니다. 반복하는 배열의 현재 값입니다.
메모는 이전 반복의 반환 값을 저장합니다.
start는 메모의 첫 번째 값으로 값을 전달하여 선택적 시작점을 제공합니다.
위의 예를 다시 살펴보겠습니다. 하지만 이번에는 각 반복에서 발생합니다.
array = [1, 1, 1]
array.reduce(0) {|sum, i| sum + i}
# 1st: 0 + 1 #=> 1
# 2nd: 1 + 1 #=> 2
# 3rd: 2 + 1 #=> 3
각 반복은 합계 값을 current_element에 추가한 다음 해당 반환값을 합계에 대한 다음 값으로 저장합니다. 반복이 끝나면 sum의 최종 값이 반환됩니다!
계속 진행하기 전에... 매개변수 값이 선택 사항이라고 말한 것을 기억하십니까? 시작 값을 전달하지 않으면 메서드는 메모의 첫 번째 값으로
array[0]
를 취하고 array[1]
로 반복을 시작합니다!array = [1, 1, 1]
array.reduce {|sum, i| sum + i} #=> 3
이제 기본 사항을 이해했으므로 .reduce가 제공해야 하는 재미있는 다용도에 대해 알아보겠습니다.
조건부 논리를 사용하여 수익 제어
글쎄, 내가 내 구충제를 잊어 버린 것 같아요. 성가신 마법사가 돌아와서 이번에는 max_by 메서드를 사용했습니다... 이 이름 그룹에서 가장 큰 이름을 어떻게 찾아야 합니까?
names = ["Gandalf", "Saruman", "Radagast"]
.reduce가 무엇을 할 수 있는지 봅시다!
names.reduce do |longest, current|
if current.length > longest.length
current
else
longest
end
end #=> 'Radagast'
일부 제어 흐름을 구현하여
names
배열의 각 값을 살펴보고 current
보다 긴 경우 longest
를 반환하거나 다음 반복을 위해 longest
의 동일한 값을 유지할 수 있습니다.다음과 같이 더 우아하게 작성할 수도 있습니다.
names.reduce do |longest, current|
current.length > longest.length ? current : longest
end #=> 'Radagast'
삼항 연산자는 .reduce 제어 흐름의 기본 중 일부를 구성합니다.
그러나 우리의 방법에는 눈에 띄는 결함이 있습니다. 두 개 이상의 이름이 길이가 같으면 어떻게 됩니까?
names = ["Bronson", "Dave", "Swanson", "Steve", "Johnson"]
현재 .reduce 메서드는
true
에 대해 current.length > longest.length
를 전달하는 후속 값이 없기 때문에 가장 긴 첫 번째 이름만 반환합니다!.reduce를 사용하여 여러 값 반환
선택적 시작 매개변수를 메서드에 전달하는 방법을 기억하십니까? 여러 응답의 배열을 반환하는 .reduce 메소드를 생성하기 위해 실제로 이것을 우리의 이점으로 사용할 수 있습니다!
names = ["Bronson", "Dave", "Swanson", "Steve", "Johnson"]
names.reduce([""]) do |long_names, current|
if current.length > long_names[0].length
[current]
elsif current.length == long_names[0].length
long_names << current
else
long_names
end
end #=> ["Bronson", "Swanson", "Johnson"]
이를 분해하려면 각 반복에서 출력을 일관되게 유지해야 하므로 문자열 배열이 필요하므로 시작 값으로 빈 문자열이 있는 배열을 넣습니다. 각 반복 후에
current
가 이전의 가장 긴 이름보다 크면 새 배열을 시작할 수 있습니다. current
가 이전의 가장 긴 이름과 길이가 같으면 배열에 추가할 수 있습니다. long_names
배열을 현재 형태로 반환합니다..reduce는 강력한 도구이므로 이것이 어떻게 작동하는지 더 명확하게 하는 데 도움이 되었기를 바랍니다. 이 열거형에는 아직 탐색할 힘이 있으므로, 앞서 언급한 sum 예제를 리팩토링하는 또 다른 방법을 알려 드리겠습니다.
array.reduce {|sum, i| sum + i}
대신 ...왜 시도하지 않습니까
array.reduce(:+)
?
Reference
이 문제에 관하여(.reduce: 다양한 배열 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/alecgrey/reduce-a-versatile-array-method-45eg텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)