4T2F / ThinkBig

🌟씽크빅 스터디🌟
5 stars 1 forks source link

Swift의 high-order functions에 대해 설명해주세요. #43

Open JooYoungNoh opened 3 months ago

JooYoungNoh commented 3 months ago

🔎 고차함수(high-order functions)란?

Map

//선언
func map<T>(_ transform: (Element) throws -> T) rethrows -> [T]

//예시
let string = ["1", "2", "3", "4", "5"]
let numbers = string.map { Int($0)! }

print(numbers)  // [1, 2, 3, 4, 5]


FlatMap

//선언
func flatMap<SegmentOfResult>(_ transform: (Self.[Element]) throws -> SegmentOfResult) rethrows -> [SegmentOfResult.[Element]] where SegmentOfResult : [Sequence]

//예시
let students = [["Mike", nil], [nil, nil, "Jane"], ["John"]]

let goodStudents = students.flatMap({$0})

print(goodStudents)
 //[Optional("Mike"), nil, nil, nil, Optional("Jane"), Optional("John")]

print(goodStudents.flatMap({$0}))
 //["Mike", "Jane", "John"]


CompactMap

//선언
func compactMap<ElementOfResult>(_ transform: (Self.[Element]) throws -> ElementOfResult?) rethrows -> [ElementOfResult]

//예시
let students = ["Mike", "Jane", nil, "John", nil]
let compactStudents = students.compactMap({$0})

print(compactStudents)  //["Mike", "Jane", "John"]


사용 예시

let ramdomScore = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let eightTeenDiscordSchool: [[(String, Int)?]] = [
    [   //eightTeenGroup
        ("강치우", ramdomScore.randomElement()!),
        ("김명현", ramdomScore.randomElement()!),
        ("노주영", ramdomScore.randomElement()!),
        ("이창준", ramdomScore.randomElement()!),
        ("최동호", ramdomScore.randomElement()!)
    ],
    [   //씽크빅1 Group
        ("김민재", ramdomScore.randomElement()!),
        ("정인선", ramdomScore.randomElement()!),
        ("황성진", ramdomScore.randomElement()!)
    ],
    [   //씽크빅2 Group
        ("김소혜", ramdomScore.randomElement()!),
        ("황민채", ramdomScore.randomElement()!),
        nil  //민영님
    ]
]

//2차원 배열 -> 1차원 배열로 변경(FlatMap)
let flatSchool = eightTeenDiscordSchool.flatMap({$0})
//[Optional(("강치우", 9)), Optional(("김명현", 3)), Optional(("노주영", 9)), Optional(("이창준", 4)), Optional(("최동호", 2)), Optional(("김민재", 2)), Optional(("정인선", 7)), Optional(("황성진", 9)), Optional(("김소혜", 9)), Optional(("황민채", 8)), nil]

//1차원 배열 -> 옵셔널 바인딩
let compactSchool = flatSchool.compactMap({$0})
//[("강치우", 1), ("김명현", 7), ("노주영", 4), ("이창준", 4), ("최동호", 3), ("김민재", 6), ("정인선", 8), ("황성진", 1), ("김소혜", 0), ("황민채", 9)]

//옵셔널 바인딩 -> 더하기
let sumScore = compactSchool.reduce(into: 0){$0 += $1.1} 
//총합

//더하기 -> [Int]형을 [String]형으로 바꿔서 결과 보여주기
let result = [sumScore].map{String($0)}
//["총합"]

//한줄 코드
let result1 = [eightTeenDiscordSchool
                    .flatMap({$0})
                    .compactMap({$0})
                    .reduce(into: 0){$0 += $1.1}
              ].map{String($0)}
//["총합"]


Filter

//선언
func filter(_ isIncluded: (Element) throws -> [Bool]) rethrows -> [Set]<Element>

//예시
let numbers = [1, 2, 3, 4, 5]
let numbersGreaterThanTwo = numbers.filter({ $0 > 2 })

print(numbersGreaterThanTwo)  //[3, 4, 5]


Reduce

//선언
func reduce<Result>(
    _ initialResult: Result,
    _ nextPartialResult: (Result, Self.[Element]) throws -> Result
) rethrows -> Result

//예시
let numbers = [1, 2, 3, 4, 5]
let numberSum = numbers.reduce(0) {$0 + $1} 
let numberSumShortcut = numbers.reduce(10, -)

print(numberSum)  //15
print(numberSumShortcut) //-5


withseon commented 3 months ago

고차함수 예시 코드와 출력 결과를 함께 확인해서 이해하기 쉬웠습니다! 고차함수에 대한 질문은 아니지만, 코드에서 사용하고 있는 throws와 rethrows의 차이가 무엇이고 어떠한 상황에 쓰는지 궁금합니다..!