나는이 두 기능 fold()
과 꽤 혼란스럽고 reduce()
Kotlin에서는 누구나이 둘을 구별하는 구체적인 예를 줄 수 있습니까?
답변
fold
는 초기 값을 취하며, 전달 된 람다의 첫 번째 호출은 해당 초기 값과 컬렉션의 첫 번째 요소를 매개 변수로받습니다.
예를 들어 정수 목록의 합계를 계산하는 다음 코드를 사용하십시오.
listOf(1, 2, 3).fold(0) { sum, element -> sum + element }
람다에 대한 첫 번째 호출은 매개 변수 0
및 1
입니다.
초기 값을 전달할 수있는 기능은 작업에 일종의 기본값 또는 매개 변수를 제공해야하는 경우에 유용합니다. 예를 들어, 목록 내에서 최대 값을 찾고 있지만 어떤 이유로 적어도 10을 반환하려는 경우 다음을 수행 할 수 있습니다.
listOf(1, 6, 4).fold(10) { max, element ->
if (element > max) element else max
}
reduce
초기 값을 사용하지 않고 대신 컬렉션의 첫 번째 요소로 누적 기 ( sum
다음 예제에서 호출 )로 시작합니다.
예를 들어, 정수를 다시합시다 :
listOf(1, 2, 3).reduce { sum, element -> sum + element }
여기서 람다에 대한 첫 번째 호출은 매개 변수 1
및 2
입니다.
reduce
작업이 적용중인 컬렉션의 값 이외의 값에 의존하지 않는 경우에 사용할 수 있습니다 .
답변
내가 부르는 주요 기능 차이 (다른 답변에 대한 의견에서 언급되었지만 이해하기 어려울 수 있음)는 빈 컬렉션에서 수행되면 reduce
예외가 발생 한다는 것 입니다.
listOf<Int>().reduce { x, y -> x + y }
// java.lang.UnsupportedOperationException: Empty collection can't be reduced.
.reduce
“데이터 없음”의 경우 어떤 값을 반환할지 알 수 없기 때문 입니다.
이 값과 대조하십시오 .fold
. 빈 컬렉션의 경우 기본값 인 “시작 값”을 제공해야합니다.
val result = listOf<Int>().fold(0) { x, y -> x + y }
assertEquals(0, result)
따라서 컬렉션을 다른 (관련되지 않은) 유형의 단일 요소로 집계하지 않으려는 경우에도 (만 .fold
허용 할 수 있음) 시작 컬렉션이 비어 있으면 컬렉션을 확인해야합니다 먼저 크기를 정한 다음 .reduce
사용하십시오..fold
val collection: List<Int> = // collection of unknown size
val result1 = if (collection.isEmpty()) 0
else collection.reduce { x, y -> x + y }
val result2 = collection.fold(0) { x, y -> x + y }
assertEquals(result1, result2)