순서가 있는 연산을 처리할 때 자주 활용하는 디자인 패턴
다른 타입의 콘텐츠(값)
을 담은 무엇(포장)
모나드의 조건을 만족하는 옵셔널
1. Wrapper타입을 인자로 받는 제네릭 타입
2. 다른 타입(아래의 예시에서 Int)의 값을 갖는 상태의 컨텍스트를 생성
Optional<Int>.init(2)
3. Int타입의 값을 전달받아 3을 더하여 반환
func addThree(_ num: Int) -> Int {
return num + 3
}
addThree(2) //5
addThree(Optional(2)) //오류 -> 맵 사용으로 해결
Optional(2).map(addThree) //Optional(5)
// 1. 컨텍스트로부터 값 추출 Optional(2) -> 2
// 2. 추출한 값을에 맵이 전달받은 함수에 전달 2 + 3 = 5
// 3. 새로운 함수객체를 반환 Optional(5)
맵(컨텍스트)과 같은 함수를 적용할 수 있는
포장된 값을 담은 컨텍스트(ex옵셔널)
예를 들어 Array, Dictionary, Set과 같은 컬렉션 타입
var value: Int? = 2
value.map{ $0 + 3 } //5
value = nil
value.map{ $0 + 3 } // nil
자신의 컨텍스트와 같은 컨텍스트의 형태로 매핑할 수 있는 함수객체
‘flatMap’ is deprecated: Please use compactMap(:) for the case where closure returns an optional value
Use 'compactMap(:)’ instead
2차원 배열을 1차원 배열로 flatten하게 만들때 flatMap을 사용.
2차원 배열에서는 둘 다 nil을 제거하지 않는다.
맵 map
플랫맵 flatMap
컴팩트맵 compactMap
내부의 값을 1차원적으로 펼쳐놓는다
let multipleContainer = [[1, 2, Optional.none], [3, Optional.none], [4, 5, Optional.none]]
let mappedMultipleContainer = multipleContainer.map{ $0.map{ $0 } }
let flatmappedMultipleContainer = multipleContainer.flatMap{ $0.compactMap{ $0 } }
print(mappedMultipleContainer) //[[Optional(1), Optional(2), nil], [Optional(3), nil], [Optional(4), Optional(5), nil]]
print(flatmappedMultipleContainer) //[1, 2, 3, 4, 5]