Swift 코딩테스트와 개발 시 유용하게 사용할 수 있는 고차 함수 및 메서드를 키워드와 함께 정리해보자. 사전처럼 참고하여 각 메서드의 기능을 알고 적절히 활용할 수 있을지도?
map
: 배열의 각 요소를 변형하여 새로운 배열로 반환함.
let numbers = [1, 2, 3]
let doubled = numbers.map { $0 * 2 } // [2, 4, 6]
filter
: 특정 조건을 만족하는 요소들만 필터링하여 새로운 배열로 반환함.
let evenNumbers = numbers.filter { $0 % 2 == 0 } // [2]
reduce
: 배열의 모든 요소를 하나의 값으로 축약함.
let sum = numbers.reduce(0) { $0 + $1 } // 6
compactMap
: nil
값을 제외하고 변환하여 새로운 배열로 반환함.
let strings = ["1", "2", "a"]
let validNumbers = strings.compactMap { Int($0) } // [1, 2]
flatMap
: 중첩된 배열을 평탄화하여 하나의 배열로 반환함.
let nestedArray = [[1, 2], [3, 4]]
let flattened = nestedArray.flatMap { $0 } // [1, 2, 3, 4]
allSatisfy
: 배열의 모든 요소가 특정 조건을 만족하는지 확인함.
let allPositive = numbers.allSatisfy { $0 > 0 } // true
contains(where:)
: 배열의 요소 중 특정 조건을 만족하는 요소가 있는지 확인함.
let hasEven = numbers.contains { $0 % 2 == 0 } // true
forEach
: 배열의 각 요소에 대해 주어진 클로저를 실행함.
numbers.forEach { print($0) } // 1, 2, 3 출력
sorted(by:)
: 배열의 요소를 지정된 기준으로 정렬함.
let sortedNumbers = numbers.sorted(by: >) // [3, 2, 1]
firstIndex(of:)
: 배열에서 특정 요소의 첫 번째 인덱스를 반환함.
let index = numbers.firstIndex(of: 2) // 1
contains
: 배열에 특정 요소가 포함되어 있는지 확인함.
let hasThree = numbers.contains(3) // true
split(separator:)
: 문자열을 특정 구분자로 나누어 배열로 반환함.
let sentence = "Hello World"
let words = sentence.split(separator: " ") // ["Hello", "World"]
joined(separator:)
: 문자열 배열을 하나의 문자열로 합침.
let joinedString = words.joined(separator: " ") // "Hello World"
max()
/ min()
: 배열의 최대값 또는 최소값을 찾음.
let maxValue = numbers.max() // 3
let minValue = numbers.min() // 1
reversed()
: 배열의 요소를 역순으로 변환하여 반환함.
let reversedNumbers = numbers.reversed() // [3, 2, 1]
enumerated()
: 배열의 인덱스와 값을 동시에 반복하고자 할 때 사용함.
for (index, value) in numbers.enumerated() {
print("\(index): \(value)")
}
// 0: 1, 1: 2, 2: 3
prefix(_:)
/ suffix(_:)
: 배열의 처음 n개의 요소 또는 마지막 n개의 요소를 반환함.
let firstTwo = numbers.prefix(2) // [1, 2]
let lastTwo = numbers.suffix(2) // [2, 3]
dropFirst(_:)
/ dropLast(_:)
: 배열에서 처음 또는 마지막 n개의 요소를 제외한 나머지를 반환함.
let droppedFirst = numbers.dropFirst(1) // [2, 3]
let droppedLast = numbers.dropLast(1) // [1, 2]
chunked(into:)
(Swift 5.8+): 배열을 특정 크기 단위로 나누고 싶을 때 사용함.
let chunks = numbers.chunked(into: 2) // [[1, 2], [3]]
zip(_:_:)
: 두 배열을 병합하여 튜플 형태의 배열을 만듦.
let names = ["Alice", "Bob"]
let scores = [90, 85]
let paired = zip(names, scores) // [("Alice", 90), ("Bob", 85)]
stride(from:to:by:)
: 특정 범위에서 간격을 설정하여 반복하는 방법임.
for value in stride(from: 0, to: 10, by: 2) {
print(value) // 0, 2, 4, 6, 8
}
Set
사용한 중복 제거: 배열에서 중복된 요소를 제거하고 고유한 값들만 남김.
let duplicates = [1, 2, 2, 3]
let uniqueElements = Array(Set(duplicates)) // [1, 2, 3]
append(_:)
/ removeLast()
: 배열을 스택처럼 사용하기 위한 메서드. 요소를 추가하고 제거함.
var stack = [1, 2, 3]
stack.append(4) // [1, 2, 3, 4]
let lastElement = stack.removeLast() // 4
removeFirst()
: 큐에서 첫 번째 요소를 제거하기 위한 메서드.
var queue = [1, 2, 3]
let firstElement = queue.removeFirst() // 1
permutations
(직접 구현 필요): 특정 배열의 모든 순열을 계산할 때 자주 구현해야 함.
func permutations<T>(_ array: [T]) -> [[T]] {
if array.count == 0 { return [[]] }
return array.indices.flatMap { i -> [[T]] in
var remainder = array
let element = remainder.remove(at: i)
return permutations(remainder).map { [element] + $0 }
}
}
combinations
(직접 구현 필요): 조합을 계산할 때 자주 구현해야 함.
func combinations<T>(_ array: [T], _ count: Int) -> [[T]] {
guard count > 0 else { return [[]] }
guard count <= array.count else { return [] }
if count == array.count { return [array] }
var result = combinations(Array(array.dropFirst()), count)
let partial = combinations(Array(array.dropFirst()), count - 1)
result += partial.map { [array.first!] + $0 }
return result
}
함수 설계 시 유의사항:
calculateSum()
처럼 명확하게 어떤 작업을 하는지 알 수 있도록 작성.조건문 작성 시 유의사항:
if let
이나 guard let
을 사용해 옵셔널 값을 안전하게 언래핑하는 것이 중요함.? :
)를 사용하여 코드의 길이를 줄일 수 있음. 예: let result = condition ? trueValue : falseValue
.&&
와 ||
를 활용해 여러 조건을 결합할 때, 괄호를 사용해 가독성을 높이는 것이 좋음.