일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- port forwarding
- 28015
- STF
- SWIFT
- create table
- ubuntu
- insert
- STF_PortForwarding
- appium
- Materials
- postgresql
- nohup
- sshpass
- openpyxl
- postgres
- nmap
- ftp
- 실행권한
- ssh
- perfect
- centos
- PYTHON
- Jupyter Notebook
- Jupyter
- nGrinder
- mysql
- appium server
- rethinkdb
- kitura
- GoCD
- Today
- Total
don't stop believing
Map 사용하기 본문
Map은 자신을 호출할 때 매개별수로 전달된 함수를 실행하여 그 결과를 다시 반환해주는 함수입니다. Swift에서 Map은 Arry, Dictionary, Set, Optional 등에서 사용할 수 있습니다. 조금 더 정확히 말하자면 Swift의 Sequence, Collection 프로토콜을 따르는 타입과 옵셔널은 모두 맵을 사용할 수 있습니다.
Map을 사용하면 컨테이너가 담고 있던 각각의 값을 매개변수를 통해 받은 함수에 적용한 후 다시 컨테이너에 포장하여 반환합니다. 기존 컨테이너의 값은 변경되지 않고 새로운 컨테이너가 생성되어 반환합니다. 그래서 Map은 기존 데이터를 변형하는 데 많이 사용 합니다.
map 메써드의 사용법은 for-in 구문과 별반 차이가 없습니다. 다만 코드의 재사용 측면이나 컴파일러 최적화 측면에서 본다면 성능 차이가 있습니다. 또, 다중 스레드 환경일때 대상 컨테이너의 값이 스레드에서 변경되는 시점에 다른 스레드에서도 동시에 값이 변경되려고 할 때 예측치 못한 결과가 발생하는 부작용을 방지할 수도 있습니다.
아래는 for-in을 이용해 Arry로 있는 숫자에 2를 곱하는 코드입니다.
let numbers: [Int] = [1, 2, 3, 4, 5, 6] var doubledNumber: [Int] = [Int]() var strings: [String] = [String]() // for 구문 사용 for number in numbers { doubledNumber.append(number * 2) strings.append("\(number)") } print(doubledNumber) // [2, 4, 6, 8, 10, 12] print(strings) // ["1", "2", "3", "4", "5", "6"]
위 코드를 map을 이용해 변경해 봅시다.
let numbers: [Int] = [1, 2, 3, 4, 5, 6] var doubledNumber: [Int] = [Int]() var strings: [String] = [String]() // map 메서드 사용 doubledNumber = numbers.map({ (number: Int) -> Int in return number * 2 }) strings = numbers.map({ (number: Int) -> String in return "\(number)" }) print(doubledNumber) // [2, 4, 6, 8, 10, 12] print(strings) // ["1", "2", "3", "4", "5", "6"]
위 map을 사용한 코드를 closure 표현식을 사용해 더 간략화해볼 수 있습니다.
let numbers: [Int] = [1, 2, 3, 4, 5, 6] var doubledNumber: [Int] = [Int]() var strings: [String] = [String]() // 기본 closure 표현식 사용 doubledNumber = numbers.map({ (number: Int) -> Int in return number * 2 }) // 매개변수 및 반환 타입 생략 doubledNumber = numbers.map({ return $0 * 2 }) // 반환 키워드 생략 doubledNumber = numbers.map({ $0 * 2 }) // 후행 closure 사용 doubledNumber = numbers.map { $0 * 2} print(doubledNumber) // [2, 4, 6, 8, 10, 12]
Closure 표현을 간략화하니 조금씩 코드가 더 간결해졌습니다. 그런데 처음에 언급했던 코드의 재사용 측면에 대해 생각해볼 필요가 있습니다. 같은 기능을 여러 번 사용할 것이라면 하나의 Closure를 여러 메서드에서 사용하는 편이 좋을 것 같습니다.
아래와 같이 재사용 가능한 코드로 재구성할 수 있습니다.
let evenNumbers: [Int] = [0, 2, 4, 6, 8] let oddNumbers : [Int] = [0, 1, 3, 5, 7] let multiplyTwo: (Int) -> Int = { $0 * 2 } let doubledEvenNumbers = evenNumbers.map(multiplyTwo) print(doubledEvenNumbers) // [0, 4, 8, 12, 16] let doubledOddNumbers = oddNumbers.map(multiplyTwo) print(doubledOddNumbers) // [0, 2, 6, 10, 14]
map 메써드는 배열에서만 사용할 수 있는 것은 아닙니다. 여러 컨테이너 타입에 모두 적용이 가능합니다.
let alphabetDictionary: [String: String] = ["a": "A", "b": "B"] // closure 기본 표현식 var keys: [String] = alphabetDictionary.map { (tuple: (String, String)) -> String in return tuple.0 } // 딕셔너리 타입의 간략화 keys = alphabetDictionary.map { $0.0 } print(keys) // 딕셔너리 타입 let values: [String] = alphabetDictionary.map { $0.1 } print(values) // Set 타입 var numberSet: Set= [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(optionalInt) // range 타입 let range: CountableClosedRange = (0...3) let resultRange: [Int] = range.map { $0 * 2 } print(resultRange)
map 메서드를 사용해 여러 자료를 손쉽게 연산할 수 있습니다.
'Swift > Basic' 카테고리의 다른 글
Reduce 사용하기 (0) | 2018.02.19 |
---|---|
Filter 사용하기 (0) | 2018.02.19 |
탈출 클로저 @escaping (0) | 2018.01.31 |
defer (후처리) (0) | 2018.01.24 |
Swift Access Control (0) | 2018.01.19 |