[Swift] 고차함수

임승섭·2023년 6월 28일
0

Swift

목록 보기
18/35

고차함수 (Higer-order Function)

  • "함수"를 파라미터로 사용하거나, 함수 실행의 결과를 "함수"로 리턴하는 함수

map

  • 기존 배열 등의 각 아이템을 새롭게 (클로저가 제공하는 방식으로) 매핑해서 새로운 배열 리턴
let numbers = [1, 2, 3, 4, 5]


numbers.map(transform: (Int) throws -> T)
// transform : 파라미터 이름, 인풋 Int, 아웃풋 T(어떠한 타입도 괜찮다), 일단 throws 무시

// 클로저 형태의 인풋 넣어주기
var newNumbers = numbers.map { num in
	return "숫자 : \(num)"
}		// 새로운 배열이 생긴다 (배열의 변형) - 새로운 배열의 원소들 타입은 String

// 파라미터 생략
newNumbers = numbers.map{ "숫자: \($0)" }


// 어떤 타입 배열이든 상관없다 (배열 상태 보고 알아서 타입이 설정됨)
var alphabet = ["A", "B", "C", "D"]
var newAlphabet = alphabet.map { (name) -> String in
	return name + "'s good"
}

var aaa = alphabet.map { str in	
	return str + "hi"
}

filter

  • 기존 배열 등의 각 아이템을 (클로저가 제공하는) 조건에 넣어서 참인 아이템만 걸러내서 새로운 배열 리턴
let names = ["Apple", "Black", "Circle", "Dream", "Blue" ]

names.filter(isIncluded: (String) throws -> Bool)

var newNames = names.filter { (name) -> Bool in 
	return name.contains("B")
}


let array = [1, 2, 3, 4, 5, 6, 7]
aray.filter(isIncluded: (Int) throws -> Bool)

var evenNumArray = array.filter { num in
	return num % 2 == 0
}

var bbb = array.filter { $0 % 2 == 0 }


// 함수로 전달
func isEven(_ i: Int) -> Bool {
	return i % 3 == 0
}
let ccc = array.filter(isEven)

// filter로 새로운 배열 만들고 바로 또 filter 적용시키기 (filter 연속 적용)
evenNumersArray = array.filter { $0 % 2 == 0 }.filter { $0 < 5 }

reduce

  • 기존 배열 등의 각 아이템을 (클로저가 제공하는 방식으로) 결합해서 마지막 결과값 리턴
  • 각 아이템을 결합해서 단 하나의 값으로 리턴한다
  • 초기값을 제공할 필요가 있다
var numArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

// 두 가지 파라미터 (initial, next)
// 뒤에가 함수형 파라미터구나!
numArray.reduce(initialResult: Result, nextPartialResult: (Result, Int) throws -> Result)

// 엔터 바로 치면 initial은 0으로 설정된다
// 그 initial 값을 처음에 sum에 저장
var resultSum = numArray.reduce(0) { (sum, num) in
	return sum + num
}

var ddd = numArray.reduce(100) { $0 - $1 }

Exercise

// 홀수만 제곱해서 그 숫자를 다 더한 값을 구하여라
numArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

var result = numArray.filter { $0 % 2 != 0 }.map {$0 * $0 }.reduce(0) { $0 + $1 }

forEach

  • 기존 배열 등의 각 아이템별로 (클로저가 제공하는) 특정 작업을 실행
let immutableArray = [1, 2, 3, 4, 5]

immutableArray.forEach(body: (Int) throws -> Void)

immutableArray.forEach { num in
	print(num)
}

immutableArray.forEach { print("숫자: \($0)") }

--

compactMap

  • 기존 배열 등의 각 아이템을 (클로저가 제공하는 방식으로) 새롭게 매핑해서 변형하되,
    Optional 요소는 제거하고, 새로운 배열 리턴
  • map + Optional 제거
let stringArray: [String?] = ["A", nil, "B", nil, "C"]

stringArray.compactMap(transform: (String?) throws -> ElementOfResult?)

var newStringArray = stringArray.compactMap { $0 }


let numbers = [-2, -1, 0, 1, 2]

var positiveNumbers = numbers.compactMap { $0 >= 0 ? $0 : nil }

// 근데 이런건 filter로도 가능
// numbers.filter { $0 >= 0 }

// 아예 filter로 compactMap을 구현해보자
newStringArray = stringArray.filter { $0 != nil }.map { $0! }

flatMap

  • 중첩된 배열의 각 배열을 (클로저가 제공하는 방식으로) 새롭게 매핑해서 내부 중첩된 배열을 제거하고 리턴
var nestedArray = [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ]
var eee = nestedArray.flatMap { $0 }

var newNestedArray = [[[1,2,3], [4,5,6], [7, 8, 9]], [[10, 11], [12, 13, 14]]]
var fff = newNestedArray.flatMap { $0 }.flatMap { $0 }

0개의 댓글