728x90
16. 맵, 필터, 리듀서
고차함수라 불리는 애들이다.
16.1 맵
맵은 collection의 값을 변경하기위해 주로 사용됩니다.
신기 했던 부분은 dictionary 컬렉션은 map으로 돌리면 내부는 튜플로 받아와지는점이 당황스러웠습니다.
반환 값은 배열로 반환해줍니다.
let numbers: [Int] = [0, 1, 2, 3, 4]
var doubleNumbers: [Int] = [Int]()
doubleNumbers = numbers.map({ (number: Int) -> Int in
return number * 2 })
doubleNumbers = numbers.map({ $0 * 2 })
print(doubleNumbers)
let alphabetDictionary: [String: String] = ["a":"A", "b":"B"]
// 튜플로 map의 전달인자로 받는다.
var keys: [String] = alphabetDictionary.map { (tuple: (String, String)) -> String in
return tuple.0
}
keys = alphabetDictionary.map{$0.0}
let values: [String] = alphabetDictionary.map{$0.1}
print(keys)
print(values)
16.2 필터
필터는 말 그대로 컨테이너 내부의 값을 걸러서 추출하는 역할의 고차함수입니다.
매개변수로 전달되는 함수의 반환 타입은 Bool 입니다. 반환 값이 true인 값들만 골라서 추출할 수 있습니다.
let numbers: [Int] = [0, 1, 2, 3, 4, 5]
let evenNumbers: [Int] = numbers.filter{ (number: Int) -> Bool in
return number % 2 == 0
}
print(evenNumbers)
let oddNumbers: [Int] = numbers.filter{$0 % 2 == 1}
print(oddNumbers)
// map 과 filter가 체인처럼 연결하여 사용 할 수 있습니다.
let chainNumbers: [Int] = numbers.map{$0 + 3}.filter{$0 % 2 == 1}
print(chainNumbers)
16.3 리듀스
리듀스는 내부의 콘텐츠를 하나로 합하는 기능을 실행하는 고차함수입니다.
배열이라면 배열의 모든 값을 전달인자로 전달받은 클로저의 연산 결과로 합해줍니다.
리듀스의 첫번째 매개변수는 초깃 값을 지정해 줄 수 있으며, 다음 매개변수는 클로저를 받습니다.
let numbers: [Int] = [1, 2, 3]
var sum: Int = numbers.reduce(0, { (result: Int, next: Int) -> Int in
print("\(result) + \(next)")
return result + next
})
print(sum)
// 초깃값이 0이고 정수 배열의 모든 값을 뺍니다.
let subtract: Int = numbers.reduce(0, { (result: Int, next: Int) -> Int in
print("\(result) - \(next)")
return result - next
})
print(subtract)
// 후행 클로저, 트레일링 클로저
// 초깃 값이 3이고 모든 값을 더합니다.
var sumFromThree: Int = numbers.reduce(3){$0 + $1}
print(sumFromThree)
// 문자열 배열을 reudce메서드를 이용해 연결
let names: [String] = ["Chope", "Jay", "Joker", "Nova"]
let reducedNames: String = names.reduce("kemi's friend : ") {
return $0 + $1 + ", "
}
print(reducedNames)
// 클로저에 Return 값이 없을 때
// 내부에서 직접 이전 값을 변경함.
sum = numbers.reduce(into: 0, { (result: inout Int, next: Int ) in
print("\(result) + \(next)")
result += next
})
print(sum) //6
var subtractFromThree: Int = numbers.reduce(into: 3, {
print("\($0) - \($1)")
$0 -= $1
})
print(subtractFromThree)
// 초깃값을 배열로 전달 할 수 도 있습니다.
// inout을 통해 참조변수를 만들어서 return값 없이 처리 할 수 있습니다.
var doubledNumbers: [Int] = numbers.reduce(into: [1,2,3], { (result: inout [Int], next: Int) in
print("result: \(result) next: \(next)")
guard next != nil else {
return
}
print("\(result) append \(next)")
result.append(next * 2)
})
print(doubledNumbers)
맵, 필터, 리듀스 메서드의 연계 사용
// 맵,필터, 리듀서 연계사용
let numbers: [Int] = [1, 2, 3, 4, 5, 6, 7]
// 짝수를 걸러내어 각 값에 3을 곱해준 후 모든 값을 더합니다.
var result: Int = numbers.filter{$0.isMultiple(of: 2)}.map{$0 * 3}.reduce(into: 0){$0 += $1}
print(result)
// 맵 필터 리듀스의 활용
enum Gender {
case male, female, unknown
}
struct Friend {
let name: String
let gender: Gender
let location: String
var age: UInt
}
var friends: [Friend] = [Friend]()
friends.append(Friend(name: "Yoobato", gender: .male, location: "발리", age: 26))
friends.append(Friend(name: "Jinso", gender: .male, location: "시드니", age: 24))
friends.append(Friend(name: "JiYoung", gender: .female, location: "서울", age: 22))
// 서울 외의 지역에 거주하며 25세 이상인 ㅊ니구
var resultFriend: [Friend] = friends.map{Friend(name: $0.name, gender: $0.gender, location: $0.location, age: $0.age + 1 )}
resultFriend = resultFriend.filter{ $0.location != "서울" && $0.age >= 25 }
let string: String = resultFriend.reduce("서울 외의 지역에 거주하며 25세 이상인 친구") {$0 + "\n" + "\($1.name)" + "\($1.gender)" + " \($1.location)" + " \($1.age)세"}
print(string)
// 서울 외의 지역에 거주하며 25세 이상인 친구
// Yoobatomale 발리 27세
// Jinsomale 시드니 25세
반응형
'Swift > Swift 기본문법' 카테고리의 다른 글
Swift 메모리 관리 ARC(Automatic Reference Counting) (0) | 2022.02.05 |
---|---|
Swift 기본 문법 - 15. Closure (0) | 2022.02.03 |
Swift 기본 문법 - 14. 접근제어 (0) | 2022.02.02 |
Swift 기본 문법 - 13. 인스턴스의 생성과 소멸 (0) | 2022.02.01 |
Swift 기본 문법 - 12. 프로퍼티와 메서드 (0) | 2022.01.30 |