티스토리 뷰

Mobile/iOS

swift. map, flatMap, compactMap

out of coding 2019. 4. 1. 18:48

map과 flatMap의 차이와 compactMap이 나온 이유를 알아보도록 합시다.

비슷하지만 아주 미묘하게 다르기는 합니다.


다음과 같은 코드가 있다고 가정을 합시다.


1
let scoresByName = ["Henk": [058], "John": [258], "Kain": ["1"], "Lee": nil]
cs


scoreByName이라는 변수에 사람의 점수를 넣어두었습니다.

이것을 map 이용하여 바로 출력을 하여 보겠습니다.


1
2
3
let mapped = scoresByName.map { $0.value.map { $0 } }
print("mapped = \(mapped)")
// 결과 : mapped = [Optional([0, 5, 8]), Optional([2, 5, 8]), Optional(["1"]), nil]
cs


결과는 순서가 보장되지 않음을 미리 말씀 드리며 중간에 값중에 optional 들어가 있어서 옵셔널로 값이 나오게 됩니다.

그럼 flatMap으로 이것을 만들어 볼게요.


1
2
3
let flatMapped = scoresByName.flatMap { $0.value }
print("flatMapped = \(flatMapped)")
// 결과 : flatMapped = [[2, 5, 8], ["1"], [0, 5, 8]]
cs


nil 포함되지 않은 결과 값으로 나오게 됩니다.

그렇지만 swift 4.1부터는 다음과 같은 warning 발생하게 됩니다.



이것은 flatMap 동작을 조금 명확하게 하고 싶어서 이름이 변경된것입니다. compactMap으로요

이전에 저희가 사용하던 flatMap 동작은 세가지로 나올수가 있었는데요.


1
2
3
Sequence.flatMap<S>(_: (Element) -> S) -> [S.Element] where S : Sequence
Optional.flatMap<U>(_: (Wrapped) -> U?) -> U?
Sequence.flatMap<U>(_: (Element) -> U?) -> [U]
cs


이렇게 세가지 타입중에 마지막타입인 Sequence에서 바로 사용할 경우에 대해서 compactMap으로 사용하여야 한다는겁니다.
위의 예제를 다시 변경을 하면


1
2
3
let compactMap = scoresByName.compactMap { $0.value }
print("compactMap = \(compactMap)")
// 결과 : compactMap = [[0, 5, 8], [2, 5, 8], ["1"]]
cs


이렇게 하면 warning 발생하지 않게 됩니다.


댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함