- νλ μ΄μμ ν¨μλ₯Ό μΈμλ‘ μ·¨νλ ν¨μ
- ν¨μλ₯Ό κ²°κ³Όλ‘ λ°ννλ ν¨μ
(β» Higher-order Functionμ΄ λκΈ° μν΄μλ ν¨μκ° First-class Citizen μ΄μ΄μΌ νλ€.)
- λ³μλ λ°μ΄ν°μ ν λΉν μ μμ΄μΌ νλ€.
- κ°μ²΄μ μΈμλ‘ λκΈΈ μ μμ΄μΌ νλ€.
- κ°μ²΄μ 리ν΄κ°μΌλ‘ 리ν΄ν μ μμ΄μΌ νλ€.
func firstClassCitizen() {
print("function call")
}
func function(_ parameter: @escaping ()->()) -> (()->()) {
return parameter
}
let returnValue = function(firstClassCitizen)
returnValue
returnValue()
- 컬λ μ μ κ° μμ(Element)μ λμΌ μ°μ°μ μ μ©νλ©°, λ°νκ°μ΄ μλ νν
let immutableArray = [1, 2, 3, 4]
for num in immutableArray {
print(num, terminator: " ")
}
print()
immutableArray.forEach { num in
print(num, terminator: " ")
}
print()
immutableArray.forEach {
print($0, terminator: " ")
}
print()
func printParam(_ num: Int) {
print(num, terminator: " ")
}
immutableArray.forEach(printParam(_:))
print()
- forEach μ for λ¬Έμ μ°¨μ΄μ μ?
- 1~10 κΉμ§μ μ«μ μ€ μ§μλ§ μΆλ ₯νλ€κ° 9κ° λλ©΄ μ’ λ£λλλ‘ forEachλ₯Ό μ΄μ©ν΄ ꡬν
print("\n---------- [ A. for vs forEach ] ----------")
/*
forλ¬Έμ λ°λ³΅λ¬Έμ΄λ―λ‘ break, continue ν€μλ μ¬μ©
forEachλ¬Έμ ν¨μ(ν΄λ‘μ Έ)μ΄λ―λ‘ break, continue λμ return ν€μλ μ¬μ©
*/
for i in 1...10 {
guard i != 9 else { break }
guard i % 2 == 0 else { continue }
print(i, terminator: " ")
}
print()
(1...10).forEach {
guard $0 < 9 else { return }
guard $0 % 2 == 0 else { return }
print($0, terminator: " ")
}
print()
- 컬λ μ μ κ° μμ(Element)μ λμΌ μ°μ°μ μ μ©νμ¬, λ³νλ μ 컬λ μ λ°ν
rint("\n---------- [ Map ] ----------")
let names = ["Chris", "Alex", "Bob", "Barry"]
names
.map { $0 + "'s name" } // [String]
.forEach { print($0) } //forEachμ°κ²°ν΄μ μΈ μ μμ.
let names2 = names.map { $0 + "'S mame"} // [String]
print(names2) //dlfjstlrdmfheh rksmd
let intArr = Array<Int>(repeating: 2, count: 10)
for (idx, value) in intArr.enumerated() {
print(idx + value)
}
// μ΄ κ°μ μλ‘μ΄ λ³μμ λ΄κ³ μΆμ λ
// forλ¬Έμ μ¬μ©ν λ°©λ²
var numArr = [Int]()
for (idx, value) in intArr.enumerated() {
numArr.append(idx + value)
}
print(numArr)
// mapμ μ¬μ©ν λ°©λ²
let indexPlusElement = intArr.enumerated().map {
return $0 + $1 //$0μ μΈλ±μ€ $1μ 벨λ₯.
}
print(indexPlusElement)
//map:μλ‘μ΄ λ°°μ΄μ λ°ννλλ‘νλ ν¨μ
//mapμ μ°λ©΄ λ°°μ΄μ΄ μ²μλΆν° λκΉμ§ λͺ¨λ μ€νμ΄ λλ©΄μ, μ λ¬λλ κ°μ λ°λΌμ λ°νκ°μ΄λ νμ
μ΄ λ¬λΌμ§. //μμ ν λ€λ₯Έ νμ
μΌλ‘ λ³ν κ°λ₯.
//intArr.map(<#T##transform: (Int) throws -> T##(Int) throws -> T#>) intλ©΄, mapμ
λ ₯μ μλμΌλ‘ transformκ°(λ°ννμ
μ΄)μ΄ (Int)λ‘ λ³νλμ΄ λμ΄.
//[""].map(<#T##transform: (String) throws -> T##(String) throws -> T#>) string
- 1~9κΉμ§μ μ«μλ₯Ό κ°κ° 2λ°°μ© κ³±ν λ°°μ΄μ λ°ν
Array(1...9)
.map{ $0 * 2 }
//κ²°κ³Ό : [2,4,6,8,10,12]
- 컬λ μ μ κ° μμλ₯Ό νκ°νμ¬ μ‘°κ±΄μ λ§μ‘±νλ μμλ§μ μλ‘μ΄ μ»¬λ μ μΌλ‘ λ°ν
print("\n---------- [ filter ] ----------")
//let names = ["Chris", "Alex", "Bob", "Barry"]
let containBNames = names
.filter { (name) -> Bool in
return name.contains("B")
}
print(containBNames)
names.filter { $0.contains("B") }
let names1 = names.filter { _ in true }
names1
var countAlexName = names.filter { $0 == "Alex" }.count
print(countAlexName)
let anotherNames = ["Alex", "Bob", "Alex", "Alex"]
countAlexName = anotherNames.filter { $0 == "Alex" }.count
print(countAlexName)
// for λ¬Έμ μ¬μ©νλ κ²½μ°
var count = 0
for name in anotherNames {
if name == "Alex" {
count += 1
}
}
print(count)
- filterλ₯Ό μ΄μ©ν΄μ 1~50μ μ«μμ€ 3μ λ°°μλ§ μΆλ ₯νκΈ°
Array(1...50)
.filter {$0.isMultiple(of: 3) }
- 컬λ μ μ κ° μμλ€μ κ²°ν©νμ¬ λ¨ νλμ νμ μ μ§λ κ°μΌλ‘ λ°ν. e.g. Int, String νμ
print("\n---------- [ reduce ] ----------\n")
/*
(1...100)
.reduce(<#T##initialResult: Result##Result#>, <#T##nextPartialResult: (Result, Int) throws -> Result##(Result, Int) throws -> Result#>)
Result Type - κ²°κ³Όλ‘ μ»κ³ μνλ κ°μ νμ
initialResult - μ΄κΈ°κ°
nextPartialResult - (μ΄μ μμκΉμ§μ κ²°κ³Όκ°, 컬λ μ
μ΄ μ§λ νμ¬ μμ)
*/
let sum1to100 = (1...100).reduce(0) { (sum: Int, next: Int) in
return sum + next
}
print(sum1to100)
// 0 + 1 = 1
// 1 + 2 = 3
// 3 + 3 = 6
// 6 + 4 = 10
// ....
print((1...100).reduce(0) { $0 + $1 })
// forλ¬Έμ μ¬μ©νλ κ²½μ°
var sum = 0
for i in 1...100 {
sum += i
}
print(sum)
//μ§μ λνλ νν X
//(1...100).reduce(0) { (sum, next) in
// sum += next
//}
// λ¬Έμμ΄μ μ«μλ‘
["100", "200"].reduce(50) { //μ΄κΉκ° 50. λ¬Έμμ΄ -> μ«μμ΄
$0 + Int($1)! // 150 + 200 = 350
}
// 50 + 100 = 150
// 150 + 200 = 350
- λ¬Έμμ΄ λ°°μ΄μ reduceλ₯Ό μ΄μ©ν΄ νλμ λ¬Έμμ΄λ‘ ν©μΉκΈ°
- μ«μ λ°°μ΄μ reduceλ₯Ό μ΄μ©ν΄ νλμ λ¬Έμμ΄λ‘ ν©μΉκΈ°
// μλ λ λͺ¨λ reduceλ₯Ό μ΄μ©ν΄ "123" μ΄λΌλ λ¬Έμμ΄μ΄ λλλ‘ λ§λ€κΈ°
let merge1 = ["1", "2", "3"].reduce("") { $0 + $1 }
print(merge1)
let merge2 = [1, 2, 3].reduce("") { $0 + String($1) }
print(merge2)
//μ λ΄μ©μ Full Syntax λ‘ νννμ λ
//[1, 2, 3]
// .reduce("") { (str: String, num: Int) in
// return str + String(num)
// }
- 컬λ μ μ κ° μμ(Element)μ λμΌ μ°μ°μ μ μ©νμ¬ λ³νλ μ 컬λ μ λ°ν
- μ΅μ λ μ κ±°
let optionalStringArr = ["A", nil, "B", nil, "C"]
print(optionalStringArr)
print(optionalStringArr.compactMap { $0 })
let numbers = [-2, -1, 0, 1, 2]
let positiveNumbers = numbers.compactMap { $0 >= 0 ? $0 : nil }
print(positiveNumbers)
print(numbers.map { $0 >= 0 ? $0 : nil })
- μ€μ²©λ 컬λ μ μ νλμ 컬λ μ μΌλ‘ λ³ν©
let nestedArr: [[Int]] = [[1, 2, 3], [9, 8, 7], [-1, 0, 1]]
print(nestedArr)
print(nestedArr.flatMap { $0 })
let nestedArr2: [[[Int]]] = [[[1, 2], [3, 4], [5, 6]], [[7, 8], [9, 10]]]
let flattenNumbers1 = nestedArr2.flatMap { $0 }
print(flattenNumbers1)
let flattenNumbers2 = flattenNumbers1.flatMap { $0 }
print(flattenNumbers2)
nestedArr2
.flatMap { $0 }
.flatMap { $0 }
β’ forEach
- 컬λ μ μ κ° μμ(Element)μ λμΌ μ°μ°μ μ μ©νλ©°, λ°νκ°μ΄ μλ νν
β’ map
- 컬λ μ μ κ° μμ(Element)μ λμΌ μ°μ°μ μ μ©νμ¬, λ³νλ μ 컬λ μ λ°ν
β’ filter
- 컬λ μ μ κ° μμλ₯Ό νκ°νμ¬ μ‘°κ±΄μ λ§μ‘±νλ μμλ§μ μλ‘μ΄ μ»¬λ μ μΌλ‘ λ°ν
β’ reduce
- 컬λ μ μ κ° μμλ€μ κ²°ν©νμ¬ λ¨μΌ νμ μΌλ‘ λ°ν. e.g. Int, String
β’ flatMap
- μ€μ²©λ 컬λ μ μ νλμ 컬λ μ μΌλ‘ λ³ν©
β’ compactMap
- 컬λ μ μ μμ μ€ μ΅μ λμ΄ μμ κ²½μ° μ κ±°
- (flatMapμΌλ‘ μ¬μ©νλ€κ° Swift 4.1 μμ compactMap μΌλ‘ λ³κ²½λ¨)
Input : myPet λ°°μ΄ μ΄μ©
[ 1λ² λ¬Έμ ]
Pet νμ
μ λ°°μ΄μ νλΌλ―Έν°λ‘ λ°μ κ·Έ λ°°μ΄μ ν¬ν¨λ Pet μ€
κ°μμ§μ λμ΄λ§μ ν©μ°ν κ²°κ³Όλ₯Ό λ°ννλ sumDogAge ν¨μ ꡬν
func sumDogAge(pets: [Pet]) -> Int
[ 2λ² λ¬Έμ ]
Pet νμ
μ λ°°μ΄μ νλΌλ―Έν°λ‘ λ°μ λͺ¨λ Petμ΄ λμ΄λ₯Ό 1μ΄μ© λ λ¨Ήμμ λμ
μνλ₯Ό μ§λ μλ‘μ΄ λ°°μ΄μ λ°ννλ oneYearOlder ν¨μ ꡬν
func oneYearOlder(of pets: [Pet]) -> [Pet]
print("\n---------- [ Practice 1 ] ----------\n")
struct Pet {
enum PetType {
case dog, cat, snake, pig, bird
}
var type: PetType
var age: Int
}
let myPet = [
Pet(type: .dog, age: 13),
Pet(type: .dog, age: 2),
Pet(type: .dog, age: 7),
Pet(type: .cat, age: 9),
Pet(type: .snake, age: 4),
Pet(type: .pig, age: 5),
]
- 1λ² λ¬Έμ
//case1
//func sumDogAge(pets: [Pet]) -> Int {
//var ageSum = 0
//for pet in pets {
//guard pet.type == .dog else { continue }
//ageSum += pet.age
//}
//return ageSum
//}
//case2
func sumDogAge(pets: [Pet]) -> Int {
return pets
.filter{ $0.type == .dog}
.reduce(0) {$0 + $1.age}
sumDogAge(pets: myPet)
- 2λ² λ¬Έμ
//case1
// func oneYearOlder(of pets: [Pet]) -> [Pet] {
// var oneYearOlderPets = [Pet]()
// for pet in pets {
// let temp = Pet(type: pet.type, age: pet.age + 1)
// oneYearOlderPets.append(temp)
// }
// return oneYearOlderPets
// }
//case 2
func oneYearOlder(of pets: [Pet]) -> [Pet] {
return pets.map {
Pet(type: $0.type, age: $0.age + 1)
}
}
let immutableArray = Array(1...40)
[ λ¬Έμ ]
immutableArray λ°°μ΄μ κ° μΈλ±μ€μ ν΄λΉ μΈλ±μ€μ μμλ₯Ό κ³±ν κ° μ€
νμλ μ μΈνκ³ μ§μμ λν΄μλ§ λͺ¨λ κ°μ λνμ¬ κ²°κ³Ό μΆλ ₯
λ¨, μλ 1 ~ 3λ²μ ν΄λΉνλ ν¨μλ₯Ό κ°κ° μ μνκ³
μ΄κ²λ€μ ν¨κ» μ‘°ν©νμ¬ μ λ¬Έμ μ κ²°κ³Όλ₯Ό λμΆν κ²
1. λ°°μ΄μ κ° μμ * index κ°μ λ°ννλ ν¨μ
2. μ§μ μ¬λΆλ₯Ό νλ³νλ ν¨μ
3. λ κ°μ μ«μλ₯Ό λνμ¬ λ°ννλ ν¨μ
let immutableAttay = Array(1...40)
//1.
func multiplyByIndex(index: Int, number: Int) -> Int {
return index * number
}
//2.
func isEven(number: Int) -> Bool {
return number & 1 == 0
}
//3.
func addTwoNumbers(lhs: Int, rhs: Int) -> Int {
return lhs + rhs
}
- κ³ μ°¨ν¨μ μ¬μ©νμ§ μμ μμ
var sum = 0
for (index, num) in immutableArray.enumerated() {
let multipliedNum = multiplyByIndex(index: index, number: num)
if isEven(number: multipliedNum) {
sum = addTwoNumbers(lhs: sum, rhs: multipliedNum)
}
}
- κ³ μ°¨ν¨μ μ¬μ© (Function as argument)
immutableArray.enumerated()
.map(multiplyByIndex(index:number:))
.filter(isEven(number:))
.reduce(0, addTwoNumbers(lhs:rhs:))
- Closures μ΄μ©
immutableArray.enumerated()
.map { (offset, element) -> Int in
return offset * element
}.filter { (element) -> Bool in
return element & 1 == 0
}.reduce(0) { (sum, nextElement) -> Int in
return sum + nextElement
}
- λ μ€μΌ μ μμ(Shorthand Argument Names)
immutableArray.enumerated()
.map { $0 * $1 }
.filter { $0 & 1 == 0 }
.reduce(0) { $0 + $1}
//map, reduceλ₯Ό μ€μΌ μ μλ μ΄μ .
//무쑰건 2κ°μΌλ κ°λ₯.
// 2κ°μ κ°μ λνλ κ².
- λ μ€μΌ μ μμ(Shorthand Argument Names)
immutableArray.enumerated()
.map(*)
.filter({ $0 & 1 == 0 })
.reduce(0, +)
- μ¬νμμ
let array = ["1j", "2d", "3", "4"]
let m1 = array.map({ Int($0) })
let f1 = array.compactMap({ Int($0) })
let m2 = array.map({ Int($0) })[0]
let f2 = array.compactMap({ Int($0) })[0]
- map - stdlib/public/core/Sequence.swift
- filter - stdlib/public/core/Sequence.swift
- swift/stdlib/public/core/FlatMap.swift