고차 함수에 대해 알아보자!
자주 쓰는 고차함수
map
맵핑 = 맵핑한다. 하나의 값을 다른값으로 대체한다 (덮어쓴다, 값을바꿀때(int), 내부값을 바꾼다 이런 개념이다.)
let numbers = [1, 2, 3, 4, 5]
let numbersPlusOne = numbers.map({$0 + 1})
let numbersPlustwo = numbers.map({$0 + 2})
print(numbersPlusOne) /=[2, 3, 4, 5, 6]
print(numbersPlustwo) /=[3, 4, 5, 6, 7]
이렇듯 $0 + n 값을 변경했을때 결과 값이 다르게 나타난다.
$0 = 하나의 변수라고 생각하면된다.
filter
filter 는 콜렉션 내부에서 조건에 맞는 데이터들만 골라 새로운 콜렉션을 생성합니다.
let numbers = [1, 2, 3, 4, 5]
let numbersGreaterThanTwo = numbers.filter({ $0 > 2 })
let numbersGreaterThanOne = numbers.filter({ $0 > 1 })
print(numbersGreaterThanTwo) /=[3, 4, 5]
print(numbersGreaterThanOne) /=[2, 3, 4, 5]
$0 의 변수에서 >n 보다 크면 그값들로 새로운 변수를 만들어 생성한다.
reduce
reduce 는 콜렉션 내부의 데이터들을 하나로 통합시킵니다.(모든 원소를 더하기)
let numbers = [1, 2, 3, 4, 5]
let numberSum = numbers.reduce(0, { $0 + $1 }) /=15
let numberSumShortcut = numbers.reduce(0, +) /=15
다른 고차함수들과는 다르게 reduce는 두 개의 인자를 받습니다. 첫번쨰 인자는 통합할 데이터의 초기 값입니다. 위 예제에서는 배열 내의 모든 정수들의 합을 구할 것이기 때문에 초기값으로 0을 지정해주었습니다. 두번째 인자는 클로저인데, 이 클로저에서는 어떻게 값을 통합할 것인지를 정의합니다. 이때 사용되는 두 파라미터 중 첫번째는 바로 이전 값에 대한 통합된 데이터를 의미하고, 두번째는 이번에 새로 통합할 데이터를 의미합니다.
CompactMap세 가지 다른 종류의 Map 고차함수를 지원합니다. 가장 기본이 되는 map과 compactMap, flatMap이 있습니다. 그 중 compactMap은 옵셔널 바인딩을 지원하는 map입니다.
let a : [String?] = ["장료", "관우", "감녕", nil, "여포", nil]
var boos = a.compactMap({ $0 }).map( { "boost-" + $0 })
print(boos)/=["boost-장료", "boost-관우", "boost-감녕", "boost-여포"]
$0 에 boost를 추가하게 됬다. ($0 = String?의값, 옵셔널 바인딩도 동시에 진행이 되었다)
FlatMap
FlatMap은 2차원 배열에 나누어져있는 데이터들을 1차원 배열로 합쳐주는 기능이 포함되어 있습니다.
let a = [["장료", "관우", "감녕", nil, "여포", nil], ["초선"]]
let aa = a.flatMap ({ $0 })
print(aa)[Optional("장료"), Optional("관우"), Optional("감녕"), nil, Optional("여포"), nil, Optional("초선")]
옵셔널 처리가 되지 않은 상태로 출력이 된다.
let a = [["장료", "관우", "감녕", nil, "여포", nil], ["초선"]]
let aa = a.flatMap ({ $0 }).compactMap({$0}) (위 CompactMap함수를 통하여 옵셔널 처리를 해준다)
print(aa)/=["장료", "관우", "감녕", "여포", "초선"]
ForEach
forEach는 for-in 구문처럼 콜렉션의 각 요소들을 뽑아낼 수 있습니다. for-in 과는 다르게 고차함수에 포함되어 있기 때문에 글로벌 스코프에서 사용했을 때도 return 을 통해 현재 반복을 종료하고 다음 반복으로 이어나갈 수 있습니다. 마치 continue처럼 동작합니다. forEach는 다른 고차함수처럼 새로운 콜렉션이나 데이터를 반환하지 않기 때문에 단순한 순회의 용도로 사용하기에 적합합니다.
let numbers = [1, 2, 3, 4, 5, 6, 7]
numbers.forEach ({
print($0)
}) /= 1\2\3\4\5\6\7