일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- create table
- openpyxl
- STF_PortForwarding
- nmap
- postgresql
- nGrinder
- ftp
- GoCD
- perfect
- appium
- centos
- postgres
- 실행권한
- sshpass
- port forwarding
- STF
- 28015
- mysql
- ssh
- SWIFT
- nohup
- kitura
- Materials
- insert
- rethinkdb
- ubuntu
- Jupyter Notebook
- Jupyter
- PYTHON
- appium server
- Today
- Total
don't stop believing
Reduce 사용하기 본문
Reduce기능은 사실 결합이라고 불려야 마땅한 기능입니다. 리듀스는 컨테이너 내부의 콘텐츠를 하나로 합하는 기능을 실행하는 고차합수입니다. 배열이라면 배열의 모든 값을 전달인자로 전달받은 클로저의 연살 결과로 합해줍니다.
Swift의 리듀스는 두 가지 형태로 구현되어 있습니다. 첫 번째 Reduce는 클로저가 각 요소를 전달받아 연산한 후 값을 다시 클로저 실행을 위해 반환하며 컨테이너를 순환하는 형태입니다.
public func reduce<Result>(_ initialResult: Result,
_ nextPartialResult: (Result, Element) throws -> Result) rethrows -> Result
initialResult이라는 이름의 매개별수로 전달되는 값을 통해 초깃값을 지정해 줄 수 있으며, nextPartialResult라는 이름의 매개변수로 클로저를 전달받습니다. nextPartialResult 클로저의 첫 번째 매개별수는 Reduce 메서드의 initialResult 매개변수를 통해 전달받은 초깃값 또는 이전 클로저의 결괏값입니다. 모든 순회가 끝나면 Reduce의 최종 결괏값이 됩니다. 두 번째 매개변수는 Reduce 메서드가 순환하는 컨테이너의 요소입니다.
두 번째 Reduce 메서드는 컨테이너를 순환하며 클로저가 실행되지만 클로저가 따로 결괏값을 반환하지 않는 형태입니다. 대신 inout 매개변수를 사용하여 초깃값에 직접 연산을 실행하게 됩니다.
public func reduce<Result>(into initialResult: Result,
_ updateAccumulatingResult: (inout Result, Element) throws -> () rethrows -> Result)
updateAccumulatingResult 매개변수로 전달받는 클로저의 매개변수 중 첫 번째 매개변수를 inout 매개변수로 사용합니다. updateAccumulatingResult 클로저의 첫 번째 매개 변수는 Reduce 메서드의 initialResult 매개별수를 이용해 전달받은 초깃값 또는 이전에 실행된 클로저 때문에 변경되어 있는 결괏값입니다. 모든 순회가 끝나면 리듀스의 최종 결괏값이 됩니다. 두 번째 매개변수는 Reduce 메서드가 순환하는 컨테이너의 요소입니다. 상황에 따러서는 Reduce를 Map과 유사하게 사용할 수도 있습니다.
첫 번째 형태인 reduce(_: _:) 메서드의 사용 코드입니다. 초깃값이 0이고 정수 배열의 모든 값을 더합니다.
let numbers: [Int] = [1, 2, 3] var sum: Int = numbers.reduce(0, { (result: Int, element: Int) -> Int in print("\(result) + \(element)") // 0 + 1 // 1 + 2 // 3 + 3 return result + element }) print(sum) // 6
초깃값이 0이고 정수 배열의 모든 값을 뺍니다.
let numbers: [Int] = [1, 2, 3] var sum: Int = numbers.reduce(0, { (result: Int, element: Int) -> Int in print("\(result) - \(element)") // 0 - 1 // -1 - 2 // -3 - 3 return result - element }) print(sum) // -6
초깃값이 3이고 정수 배열의 모든 값을 더합니다. Closure 표현식을 사용해 간결하게 합니다.
let numbers: [Int] = [1, 2, 3] var sumFromThree: Int = numbers.reduce(3) { print("\($0) + \($1)") // 3 + 1 // 4 + 2 // 6 + 3 return $0 + $1 } print(sumFromThree) // 9
초깃값이 3이고 정수 배열의 모든 값을 뺍니다. Closure 표현식을 사용해 간결하게 합니다.
let numbers: [Int] = [1, 2, 3] var subtractFromThree: Int = numbers.reduce(3) { print("\($0) - \($1)") // 3 - 1 // 2 - 2 // 0 - 3 return $0 + $1 } print(subtractFromThree) // -3
문자열 배열을 reduce(_: _:) 메서드를 이용해 연결시킬수 있습니다.
let names: [String] = ["Chope", "Jay", "Joker", "Nova"] let reduceNames: String = names.reduce("tongchun's friend : ") { return $0 + ", " + $1 } print(reduceNames) // tongchun's friend : "Chope", "Jay", "Joker", "Nova"
두 번째 형태인 reduce(into: _:) 메서드를 사용해 보겠습니다.
초깃값이 0이고 정수 배열의 모든 값을 더합니다. 첫 번째 Reduce 형태와 달리 Closure의 값을 반환하지 않고 내부에서 직접 이전 값을 변경한다는 점이 다릅니다.
let numbers: [Int] = [1, 2, 3] var sum = numbers.reduce(into: 0, { (result: inout Int, element: Int) in // 0 + 1 // 1 + 2 // 3 + 3 print("\(result) + \(element)") result += element }) print(sum) // 6
초깃값이 3이고 정수 배열의 모든 값을 뺍니다.
let numbers: [Int] = [1, 2, 3] var sum = numbers.reduce(into: 3, { (result: inout Int, element: Int) in // 0 + 1 // 1 + 2 // 3 + 3 print("\(result) - \(element)") result -= element }) print(sum) // -3
첫 번째 Reduce 형태와 다르기 때문에 다른 컨테이너에 값을 변경하여 넣어줄 수도 있습니다. 이렇게 하면 맵이나 필터와 유사한 형태로 사용할 수도 있습니다.
홀수는 걸러내고 짝수만 두 배로 변경하여 초깃값인 [1, 2, 3] 배열에 직접 연산합니다.
let numbers: [Int] = [1, 2, 3] var doubledNumbers: [Int] = numbers.reduce(into: [1, 2]) {(result: inout [Int], element: Int) in print("reslt: \(result) element: \(element)") // result: [1, 2] element: 1 // result: [1, 2] element: 2 // result: [1, 2, 4] element: 3 guard element % 2 == 0 else { return } print("\(result) append \(element)") // [1, 2] append 2 result.append(element * 2) } print(doubledNumbers) // [1, 2, 4]
위 Reduce 코드를 Map과 Filter를 사용한 코드입니다.
let numbers: [Int] = [1, 2, 3] let doubledNumber = [1, 2] + numbers.filter { $0 % 2 == 0 }.map { $0 * 2} print(doubledNumber) // [1, 2, 4]
이름을 모두 대문자로 변환하여 초깃값인 빈 배열에 직접 연산합니다.
let names: [String] = ["Chope", "Jay", "Joker", "Nova"] var upperCasedName: [String] upperCasedName = names.reduce(into: [], { $0.append($1.uppercased()) }) print(upperCasedName) // ["CHOPE", "JAY", "JOKER", "NOVA"]
Map을 사용한 대문자 변환은 아래와 같습니다.
let names: [String] = ["Chope", "Jay", "Joker", "Nova"] var upperCasedName: [String] upperCasedName = names.map { $0.uppercased() } print(upperCasedName) // ["CHOPE", "JAY", "JOKER", "NOVA"]
'Swift > Basic' 카테고리의 다른 글
Filter 사용하기 (0) | 2018.02.19 |
---|---|
Map 사용하기 (0) | 2018.02.19 |
탈출 클로저 @escaping (0) | 2018.01.31 |
defer (후처리) (0) | 2018.01.24 |
Swift Access Control (0) | 2018.01.19 |