|
| 1 | +/* |
| 2 | +고차함수 |
| 3 | +고차함수(Higher-order function)은 ‘다른 함수를 전달인자로 받거나 |
| 4 | +함수실행의 결과를 함수로 반환하는 함수’를 뜻합니다. |
| 5 | + |
| 6 | +스위프트의 함수(클로저)는 일급시민이기 때문에 함수의 전달인자로 전달할 수 있으며, |
| 7 | +함수의 결과값으로 반환할 수 있습니다. |
| 8 | + |
| 9 | +이번 파트에서는 스위프트 표준라이브러리에서 제공하는 유용한 고차함수에 대해 알아봅니다. |
| 10 | + |
| 11 | +map |
| 12 | +filter |
| 13 | +reduce |
| 14 | +map, filter, reduce 함수는 스위프트 표준 라이브러리의 컨테이너 타입(Array, Set, Dictionary 등)에 구현되어 있습니다. |
| 15 | + |
| 16 | + |
| 17 | +*/ |
| 18 | + |
| 19 | +/* |
| 20 | +map |
| 21 | +map함수는 컨테이너 내부의 기존 데이터를 변형(transform)하여 새로운 컨테이너를 생성합니다. |
| 22 | + |
| 23 | +변형하고자 하는 numbers와 변형 결과를 받을 doubledNumbers, strings |
| 24 | +*/ |
| 25 | +let numbers: [Int] = [0, 1, 2, 3, 4] |
| 26 | +var doubledNumbers: [Int] |
| 27 | +var strings: [String] |
| 28 | + |
| 29 | +//기존의 for 구문 사용 |
| 30 | + |
| 31 | +doubledNumbers = [Int]() |
| 32 | +strings = [String]() |
| 33 | + |
| 34 | +for number in numbers { |
| 35 | + doubledNumbers.append(number * 2) |
| 36 | + strings.append("\(number)") |
| 37 | +} |
| 38 | + |
| 39 | +print(doubledNumbers) // [0, 2, 4, 6, 8] |
| 40 | +print(strings) // ["0", "1", "2", "3", "4"] |
| 41 | + |
| 42 | + |
| 43 | +//map 메서드 사용 : map 전달인자 자리에 클로저가 들어옴 |
| 44 | +// map은 각각의 요소하나를 가져다가 어떻게 변형해서 어떤것으로 돌려줄거냐 |
| 45 | +// 지정해줄수가 있음 |
| 46 | + |
| 47 | +// numbers의 각 요소를 2배하여 새로운 배열 반환 |
| 48 | +doubledNumbers = numbers.map({ (number: Int) -> Int in |
| 49 | + return number * 2 |
| 50 | +}) |
| 51 | + |
| 52 | +// numbers의 각 요소를 문자열로 변환하여 새로운 배열 반환 |
| 53 | +strings = numbers.map({ (number: Int) -> String in |
| 54 | + return "\(number)" |
| 55 | +}) |
| 56 | + |
| 57 | +print(doubledNumbers) // [0, 2, 4, 6, 8] |
| 58 | +print(strings) // ["0", "1", "2", "3", "4"] |
| 59 | + |
| 60 | + |
| 61 | +// 매개변수, 반환 타입, 반환 키워드(return) 생략, 후행 클로저 |
| 62 | +doubledNumbers = numbers.map { $0 * 2 } |
| 63 | +print(doubledNumbers) // [0, 2, 4, 6, 8] |
| 64 | + |
| 65 | + |
| 66 | +//filter |
| 67 | +//filter함수는 컨테이너 내부의 값을 걸러서 새로운 컨테이너로 추출합니다. |
| 68 | +// 즉 조건에 부합 해는 애들만 필터링 해서 새로운 컨테이너로 만들어 주겠다라는 뜻임 |
| 69 | + |
| 70 | +//기존의 for 구문 사용 |
| 71 | +// 변수 사용에 주목하세요 |
| 72 | +var filtered: [Int] = [Int]() |
| 73 | + |
| 74 | +for number in numbers { |
| 75 | + if number % 2 == 0 { |
| 76 | + filtered.append(number) |
| 77 | + } |
| 78 | +} |
| 79 | + |
| 80 | +print(filtered) // [0, 2, 4] |
| 81 | + |
| 82 | + |
| 83 | +//filter 메서드 사용 |
| 84 | +// 위에는 변수로 해서 따로 받았는데 filter 메서드 사용하면 |
| 85 | +// 상수에 바로 저장 할수 있는게 장점임 |
| 86 | + |
| 87 | +// numbers의 요소 중 짝수를 걸러내어 새로운 배열로 반환 |
| 88 | +let evenNumbers: [Int] = numbers.filter { (number: Int) -> Bool in |
| 89 | + return number % 2 == 0 // 참일때만 들어감 |
| 90 | +} |
| 91 | +print(evenNumbers) // [0, 2, 4] |
| 92 | + |
| 93 | +// 매개변수, 반환 타입, 반환 키워드(return) 생략, 후행 클로저 |
| 94 | +let oddNumbers: [Int] = numbers.filter { |
| 95 | + $0 % 2 != 0 |
| 96 | +} |
| 97 | + |
| 98 | +print(oddNumbers) // [1, 3] |
| 99 | + |
| 100 | + |
| 101 | + |
| 102 | + |
| 103 | +//reduce |
| 104 | +// reduce함수는 컨테이너 내부의 콘텐츠를 하나로 통합합니다. |
| 105 | + |
| 106 | +// 통합하고자 하는 someNumbers |
| 107 | + |
| 108 | +let someNumbers: [Int] = [2, 8, 15] |
| 109 | + |
| 110 | +//기존의 for 구문 사용 |
| 111 | +// 변수 사용에 주목하세요 |
| 112 | +var result: Int = 0 |
| 113 | + |
| 114 | +// someNumbers의 모든 요소를 더합니다 |
| 115 | +for number in someNumbers { |
| 116 | + result += number |
| 117 | +} |
| 118 | + |
| 119 | +print(result) // 25 |
| 120 | + |
| 121 | +//reduce 메서드 사용 |
| 122 | + |
| 123 | +// 초깃값이 0이고 someNumbers 내부의 모든 값을 더합니다. |
| 124 | +let sum: Int = someNumbers.reduce(0, { (first: Int, second: Int) -> Int in |
| 125 | + //print("\(first) + \(second)") //어떻게 동작하는지 확인해보세요 |
| 126 | + return first + second |
| 127 | +}) |
| 128 | + |
| 129 | +print(sum) // 25 |
| 130 | + |
| 131 | +// 초깃값이 0이고 someNumbers 내부의 모든 값을 뺍니다. |
| 132 | +var subtract: Int = someNumbers.reduce(0, { (first: Int, second: Int) -> Int in |
| 133 | + //print("\(first) - \(second)") //어떻게 동작하는지 확인해보세요 |
| 134 | + return first - second |
| 135 | +}) |
| 136 | + |
| 137 | +print(subtract) // -25 |
| 138 | + |
| 139 | +// 초깃값이 3이고 someNumbers 내부의 모든 값을 더합니다. |
| 140 | +let sumFromThree = someNumbers.reduce(3) { $0 + $1 } |
| 141 | + |
| 142 | +print(sumFromThree) // 28 |
| 143 | + |
| 144 | +//reduce 메서드에 전달하는 클로저의 매개변수 이름을 first, second |
| 145 | +//보다는 result, currentItem과 같은 이름으로 정정하는 것이 좋겠습니다. |
| 146 | +//첫 번째 매개변수는 초깃값으로부터 출발하여 마지막 요소까지 순회하는 내내의 결괏값입니다. |
| 147 | +// currentItem은 현재 순회하고 있는 요소의 값을 뜻합니다. 결국 return result + currentItem이라고 표현한다면 |
| 148 | +// 이제까지 더해진 결괏값에 이번 요소의 값을 더한다는 뜻이 되겠습니다. |
0 commit comments