[Swift] map & flatmap

나는 사과·2021년 2월 26일
0

TIL

목록 보기
3/17

모나드라는 개념을 보다가 map과 flatmap의 차이점에 대해서 정리해보려고 한다.

먼저, Swift 4.1 버전 이후부터는 compactMap이라는 것도 생기게 되었는데 이것은 flatmap과 사용방법은 같지만 Sequence타입이 옵셔널 타입의 Element를 포장한 경우에 이러한 이름으로 사용이 된다.

간단한 예를 보면..

let optionalValue: [Int?] = [3, nil, 2, 5]

let mappedValue: [Int?] = optionalValue.map{ $0 }
let compactMapValue: [Int] = optionalValue.compactMap{ $0 }

print(mappedValue)
// 출력하면 [Optional(3), nil, Optional(2), Optional(5)]
print(compactMapValue)
// [3, 2, 5]

이처럼 map은 [Int?]타입 값이 반환되는 반면에 CompactMap은 [Int]타입 값이 반환이 된다. 물론 compactMap 대신에 flatMap을 사용해도 결과는 동일하다.

체인 형식으로 표현했을 때도 둘의 차이가 나타난다.

// 문자열 -> 정수 함수
func stringToInt(string: String) -> Int? {
	return Int(string)
}
// 정수 -> 문자열 함수
func intToString(int: Int) -> String? {
	return "\(int)"
}
var optionalString: String? = "55"

let resultFlatmap = optionalString.flatmap(stringToInt)
                           .flatmap(intToString)
                           .flatmap(stringToInt)

print(resultFlatmap)  // Optional(55)

let resultMap = optionalString.map(stringToInt) // map은 체인 연결이 불가능

print(resultMap)  // Optional(Optional(55))

위 예제처럼, flatMap은 체인형태로 계속 연결하면서 사용이 가능하지만 map은 불가능하다. 이유는 map은 옵셔널하지 않은 값을 반환하지만, flatMap은 옵셔널 값을 반환하기 때문이다.
map은 옵셔널하지 않은 값을 반화하지만 map에 매개변수로 들어가는 함수인 stringToInt는 반환 값이 Int?이다. 그럼 optionalStringOptional(55)stringToInt함수에 들어갔다 오면 Optional(Optional(55))값이 반환되는 것 이다. 그래서 체인 형태로 구현하지 못하는 것이다.
반면, flatmap은 옵셔널 값을 반환하고 stringToInt함수도 Int?를 반환하기 때문에 flatmap의 값이 그대로 반환되는 것 이다. 그래서 마지막 출력 값도 그대로의 값인 Optioanl(55)인 것 이다.

0개의 댓글