Swift
Swift | 고차함수 - map vs flatmap vs compactmap
iOSDEv
2024. 2. 7. 14:40
map

⭐️ 각 요소에 대해 동일한 연산을 수행하고 그 결과를 새로운 컬렉션으로 반환하는 고차함수⭐️
- 함수를 인자로 받아 각 요소에 함수를 적용하고 그 결과 새로운 컬렉션을 반환하므로 코드의 ⭐️간결 ⭐️가독성의 장점이 있다
기본형식
let newArray = array.map { (element) -> T in
// 변환 로직
}
예제
let numbers = [1, 2, 3, 4, 5]
let squaredNumbers = numbers.map { (number) -> Int in
return number * number
}
print(squaredNumbers) // 출력: [1, 4, 9, 16, 25]
let numbers = [1, 2, 3, 4, 5]
let squaredNumbers = numbers.map { $0 * $0 }
print(squaredNumbers) // 출력: [1, 4, 9, 16, 25]
let dictionary = ["a": 1, "b": 2, "c": 3]
let squaredValues = dictionary.map { (key, value) -> Int in
return value * value
}
print(squaredValues) // 출력: [1, 4, 9]
let cast = ["Vivien", "Marlon", "Kim", "Karl"]
let lowercaseNames = cast.map { $0.lowercased() }
// 'lowercaseNames' == ["vivien", "marlon", "kim", "karl"]
let letterCounts = cast.map { $0.count }
// 'letterCounts' == [6, 6, 3, 4]
flatMap

⭐️말그대로 각 요소에 대해 매핑된 결과를 평평~하게 하나의 컬렉션으로 반환⭐️
⭐️(중첩된 컬렉션 이중 배열이라던가(배열안의 배열) 평탄화 하거나 옵셔널 값을 추출할 때 유용하게 사용된다⭐️
기본형식
let flattenedArray = array.flatMap { (element) -> T? in
// 매핑 및 평탄화 로직
}
예시
- flatMap은 이중 배열(다차원적 배열) -> 일차 배열 평평하게 변경해줌
let nestedArray = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
let flattenedArray = nestedArray.flatMap { $0 }
print(flattenedArray) // 출력: [1, 2, 3, 4, 5, 6, 7, 8, 9]
- $0은 클로저의 첫번째 인자인 현재 요소를 나타냄 flatMap은 각 배열의 요소를 하나로 평탄화하여 일차배열을 생성해낸다
- 이중 배열 -> 일차 배열
- 옵셔널값을 자동으로 추출해주고 nil값은 자동으로 제거해줌
let optionalValues: [Int?] = [1, 2, nil, 4, nil, 6]
let nonNilValues = optionalValues.flatMap { $0 }
print(nonNilValues) // 출력: [1, 2, 4, 6]
let numbers = [1, 2, 3, 4]
let mapped = numbers.map { Array(repeating: $0, count: $0) }
// [[1], [2, 2], [3, 3, 3], [4, 4, 4, 4]]
let flatMapped = numbers.flatMap { Array(repeating: $0, count: $0) }
// [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
compactMap

⭐️기존 배열 등 각 아이템을 새롭게 매핑해서 변형하고 옵셔널 요소는 제거하고 새로운 배열을 만들어냄⭐️
⭐️map + 옵셔널 즉 옵셔널 바인딩 기능이 내장되어있다
배열이 1차 배열 2차 배열이건 1차배열로 만들지 않고 형식 그대로 유지
예시
let possibleNumbers = ["1", "2", "three", "///4///", "5"]
let mapped: [Int?] = possibleNumbers.map { str in Int(str) }
// [1, 2, nil, nil, 5]
let compactMapped: [Int] = possibleNumbers.compactMap { str in Int(str) }
// [1, 2, 5]
let numbers = [-2, -1, 0, 1, 2]
//정수가 음수면 nil반환
var positiveNumbers = numbers.compactMap { $0 >= 0 ? $0 : nil }
print(positiveNumbers)
// 사실 이런 경우는 filter로 가능
//numbers.filter { $0 >= 0 }
// compactMap은 아래와 같은 방식으로도 구현 가능
// 옵셔널 문자열이기 때문에 강제로 벗겨야하기 때문에 !를 붙여야한다
newStringArray = stringArray.filter { $0 != nil }.map { $0! }
print(newStringArray)
결론
프로그래머스에서 자주 등장하여 쉽게 풀 수 있는 고차함수인 map
보통 map을 사용하게되면 optional type이기 때문에 !를 사용해야하며
compactmap / flatmap은 둘 다 기본 옵셔널을 벗겨서 기본 타입으로 나오기 때문에 편리하다
그리고 flatmap은 다차원배열이라도 1차원으로 만들어주는 아이라고 간단하게 기억하기로 했다