일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- PHP
- c언어
- OSI
- level13
- pwnable.kr
- 암호수학
- web
- SWiFT
- 파이썬
- windosw 문자열
- 미로 탐색 알고리즘
- 스택
- Stack
- 정렬 알고리즘
- LoB
- 재귀
- windosws wbcs
- 자료구조
- Java
- C
- 큐
- War Game
- 백준
- 두근두근 자료구조
- System
- HTML
- 시간복잡도
- ftz level13
- ftz
- 파일 시스템
- Today
- Total
나의 기록, 현진록
[Swift] 15.1 맵 본문
스위프트 프로그래밍 3판 - 야곰 지음
스위프트는 함수를 일급 객체로 취급합니다. 따라서 함수를 다른 함수의 전달인자로 사용할 수 있습니다. 매개변수로 함수를 갖는 함수를 고차함수라고 부르는데, 스위프트에 유용한 대표적인 고차함수로는 맵 필터 리듀스 등이 있습니다. 이번 장에서는 맵, 필터, 리듀스를 통해 데이터의 연산을 쉽게 실행하는 방법을 알아보겠습니다.
15.1 맵
맵은 자신을 호출할 때 매개변수로 전달된 함수를 실행하여 그 결과를 다시 반환해주는 함수입니다. 스위프트에서 맵은 배열, 딕셔너리, 세트, 옵셔널 등에서 사용할 수 있습니다. 조금 더 정확히 말하자면 스위프트의 Sequence, Collection 프로토콜을 따르는 타입과 옵셔널은 모두 맵을 사용할 수 있습니다.
맵을 사용하면 컨테이너가 담고 있던 각각의 값을 매개변수를 통해 받은 함수에 적용한 후 다시 컨테이너에 포장하여 반환합니다. 기존 컨테이너의 값은 변경되지 않고 새로운 컨테이너가 생성되어 반환됩니다. 그래서 맵은 기존 데이터를 변형하는데 많이 사용합니다.
map 메서드의 사용법은 앞서 알아본 for-in 구문과 별반 차이가 없습니다. 다만 코드의 재사용 측면이나 컴파일러 최적화 측면에서 본다면 성능 차이가 있습니다. 또, 다중 스레드 환경일 때 대상 컨테이너의값이 스레드에서 변경되는 시점에 다른 스레드에서도 동시에 값이 변경되려고 할 때 예측치 못한 결과가 발생하는 부작용을 방지할 수도 있습니다.
다음은 for-in 구문과 map 메서드의 비교이다.
let numbers = [0,1,2,3,4]
var doubledNumbers = [Int]()
var strings = [String]()
//for 구문 사용
for number in numbers{
doubledNumbers.append(number*2)
strings.append("\(number)")
}
print(doubledNumbers)
print(strings)
//map 메서드 사용
doubledNumbers = numbers.map({(number: Int) -> Int in
return number * 2
})
strings = numbers.map({(number: Int) -> String in
return "\(number)"
})
print(doubledNumbers)
print(strings)
map 메서드를 사용하여 코드가 조금 더 간략해지긴 했지만, 우리가 배웠던 클로저 표현식을 사용하여 표현을 더 간략화해볼 수 있습니다.
let numbers = [0,1,2,3,4]
//기존 클로저 표현 사용
var doubledNumbers = numbers.map({(number: Int) -> Int in
return number * 2
})
print(doubledNumbers)
//매개변수 및 반환 타입 생략
doubledNumbers = numbers.map({return $0 * 2})
print(doubledNumbers)
//반환 키워드 생략
doubledNumbers = numbers.map({$0 * 2})
print(doubledNumbers)
//후행 클로저 사용
doubledNumbers = numbers.map{$0 * 2}
print(doubledNumbers)
클로저 표현을 간략화하니 조금씩 코드가 간결해졌습니다. 그런데 처음 언급했던 코드의 재사용 측면에 대해 생각해볼 필요가 있습니다. 같은 기능을 여러 번 사용할 것이라면 하나의 클로저를 여러 map 메서드에서 사용하는 편이 좋을 것 같습니다.
let evenNumbers = [0,2,4,6,8]
let oddNumbers = [0,1,3,5,7]
let multiplyTwo = {$0 * 2}
let doubledEvenNumbers = evenNumbers.map(multiplyTwo)
print(doubledEvenNumbers)
let doubledOddNumbers = oddNumbers.map(multiplyTwo)
print(doubledOddNumbers)
map 메서드는 배열에서만 사용할 수 있는 것이 아닙니다. 여러 컨테이너 타임에 모두 적용 가능합니다.
let alphabetDictionary: [String: String] = ["a":"A", "b":"B"]
var keys: [String] = alphabetDictionary.map{(tuple: (String, String)) ->
String in
return tuple.0
}
keys = alphabetDictionary.map{$0.0}
let values = alphabetDictionary.map{$0.1}
print(keys)
print(values)
var numberSet: Set<Int> = [1,2,3,4,5]
let resultSet = numberSet.map{$0*2}
print(resultSet)
let optionalInt: Int? = 3
let resultInt: Int? = optionalInt.map{$0*2}
print(resultInt) //경고가 발생하는 이유는 타입캐스팅에서 설명합니다.
let range: CountableClosedRange = (0...3)
let resultRange: [Int] = range.map{$0 * 2}
print(resultRange)
'Programming > Swift' 카테고리의 다른 글
[Swift] 15.2 필터 (0) | 2021.09.14 |
---|---|
[Swift] 14.2 빠른 종료 (0) | 2021.09.13 |
[Swift] 14.1 옵셔널 체이닝 (0) | 2021.09.13 |
[Swift] Baekjoon 20300 서강근육맨 (0) | 2021.09.09 |
[Swift] 13.4 값 획득 (0) | 2021.09.07 |