๊ธ€ ์ž‘์„ฑ์ž: ๊ฐœ๋ฐœํ•˜๋Š” ํ›ˆ์ด

๊ณ ์ฐจ ํ•จ์ˆ˜ (High Order Function)

๊ณ ์ฐจํ•จ์ˆ˜๋Š” ๋‹ค๋ฅธ ํ•จ์ˆ˜๋ฅผ ์ธ์ž๋กœ ๋ฐ›๊ฑฐ๋‚˜, ํ•จ์ˆ˜์˜ ๊ฒฐ๊ณผ๋กœ ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์Šค์œ„ํ”„ํŠธ์—์„œ๋Š” map, filter, reduce ๊ฐ€ ์ฝœ๋ ‰์…˜ ํƒ€์ž… ๋‚ด์— ์ •์˜๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

 

์ง„์งœ ์ž์ฃผ์“ฐ๋Š” ๊ณ ์ฐจํ•จ์ˆ˜๋“ค(map, filter, reduce)

map

map ์€ ์ฝœ๋ ‰์…˜ ๋‚ด๋ถ€์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€๊ณตํ•˜์—ฌ ์ƒˆ๋กœ์šด ์ฝœ๋ ‰์…˜์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

let numbers = [1, 2, 3, 4, 5]
let numbersPlusOne = numbers.map({ $0 + 1 })

map ๋ฉ”์„œ๋“œ๋Š” ์ธ์ž๋กœ ํด๋กœ์ €๋ฅผ ๋ฐ›์•„ ์ปจํ…Œ์ด๋„ˆ ๋‚ด๋ถ€์— ๋“ค์–ด์žˆ๋Š” ์š”์†Œ๋“ค์˜ ๊ฐ’์„ ์–ด๋–ป๊ฒŒ ๋ฐ”๊ฟ€ ๊ฒƒ์ธ์ง€ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค.

filter

filter ๋Š” ์ฝœ๋ ‰์…˜ ๋‚ด๋ถ€์—์„œ ์กฐ๊ฑด์— ๋งž๋Š” ๋ฐ์ดํ„ฐ๋“ค๋งŒ ๊ณจ๋ผ ์ƒˆ๋กœ์šด ์ฝœ๋ ‰์…˜์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

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

filter ๋ฉ”์„œ๋“œ๋Š” ํด๋กœ์ €๋ฅผ ์ธ์ž๋กœ ๋ฐ›๊ณ , ์ด ํด๋กœ์ € ๋‚ด๋ถ€์—๋Š” ์–ด๋–ค ๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จ์‹œํ‚ฌ์ง€ ๊ทธ ์กฐ๊ฑด์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.

reduce

reduce ๋Š” ์ฝœ๋ ‰์…˜ ๋‚ด๋ถ€์˜ ๋ฐ์ดํ„ฐ๋“ค์„ ํ•˜๋‚˜๋กœ ํ†ตํ•ฉ์‹œํ‚ต๋‹ˆ๋‹ค.

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

๋‹ค๋ฅธ ๊ณ ์ฐจํ•จ์ˆ˜๋“ค๊ณผ๋Š” ๋‹ค๋ฅด๊ฒŒ reduce๋Š” ๋‘ ๊ฐœ์˜ ์ธ์ž๋ฅผ ๋ฐ›์Šต๋‹ˆ๋‹ค. ์ฒซ๋ฒˆ์จฐ ์ธ์ž๋Š” ํ†ตํ•ฉํ•  ๋ฐ์ดํ„ฐ์˜ ์ดˆ๊ธฐ ๊ฐ’์ž…๋‹ˆ๋‹ค. ์œ„ ์˜ˆ์ œ์—์„œ๋Š” ๋ฐฐ์—ด ๋‚ด์˜ ๋ชจ๋“  ์ •์ˆ˜๋“ค์˜ ํ•ฉ์„ ๊ตฌํ•  ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ์ดˆ๊ธฐ๊ฐ’์œผ๋กœ 0์„ ์ง€์ •ํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค. ๋‘๋ฒˆ์งธ ์ธ์ž๋Š” ํด๋กœ์ €์ธ๋ฐ, ์ด ํด๋กœ์ €์—์„œ๋Š” ์–ด๋–ป๊ฒŒ ๊ฐ’์„ ํ†ตํ•ฉํ•  ๊ฒƒ์ธ์ง€๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ์ด๋•Œ ์‚ฌ์šฉ๋˜๋Š” ๋‘ ํŒŒ๋ผ๋ฏธํ„ฐ ์ค‘ ์ฒซ๋ฒˆ์งธ๋Š” ๋ฐ”๋กœ ์ด์ „ ๊ฐ’์— ๋Œ€ํ•œ ํ†ตํ•ฉ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์˜๋ฏธํ•˜๊ณ , ๋‘๋ฒˆ์งธ๋Š” ์ด๋ฒˆ์— ์ƒˆ๋กœ ํ†ตํ•ฉํ•  ๋ฐ์ดํ„ฐ๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

 

์Šค์œ„ํ”„ํŠธ์—์„œ๋Š” ์‚ฌ์น™์—ฐ์‚ฐ์ž๋„ ํ•จ์ˆ˜(ํด๋กœ์ €)์ด๋ฏ€๋กœ ์—ฐ์‚ฐ์ž๋งŒ ๋„ฃ์–ด์ฃผ์–ด๋„ ๋™์ผํ•˜๊ฒŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค!

๊ณ ์˜ค๊ธ‰ ๊ณ ์ฐจํ•จ์ˆ˜๋“ค(CompactMap, FlatMap, ForEach)

CompactMap

์Šค์œ„ํ”„ํŠธ์—์„œ๋Š” ์„ธ ๊ฐ€์ง€ ๋‹ค๋ฅธ ์ข…๋ฅ˜์˜ Map ๊ณ ์ฐจํ•จ์ˆ˜๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ€์žฅ ๊ธฐ๋ณธ์ด ๋˜๋Š” map๊ณผ compactMap, flatMap์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ์ค‘ compactMap์€ ์˜ต์…”๋„ ๋ฐ”์ธ๋”ฉ์„ ์ง€์›ํ•˜๋Š” map์ž…๋‹ˆ๋‹ค.

let students : [String?] = ["Mike", "Jane", nil, "John", nil]

์œ„์™€ ๊ฐ™์ด nil์ด ์„ž์—ฌ ์žˆ๋Š” ์ฝœ๋ ‰์…˜์—์„œ ์กด์žฌํ•˜๋Š” ๋ชจ๋“  ์ด๋ฆ„ ์•ž์— "Boost2021-" ์ด๋ผ๋Š” ํ‚ค์›Œ๋“œ๋ฅผ ๋ถ™์—ฌ์ฃผ๊ณ  ์‹ถ๋‹ค๊ณ  ํ•ด๋ด…์‹œ๋‹ค. ๋‹จ์ˆœํžˆ map ์„ ํ†ตํ•ด ์•„๋ž˜์™€ ๊ฐ™์ด ์ฝ”๋“œ๋ฅผ ์ง ๋‹ค๋ฉด

let students : [String?] = ["Mike", "Jane", nil, "John", nil]
let boostStudents = students.map({ "BoostCamp2021" + $0 })

๋‹ค์Œ๊ณผ ๊ฐ™์€ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

 

 

students ๋ฐฐ์—ด ๋‚ด๋ถ€์— ์žˆ๋Š” ๋ฐ์ดํ„ฐ๋“ค์€ ๋ชจ๋‘ ์˜ต์…”๋„ํƒ€์ž…์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์—ฌ๊ธฐ์„œ ์˜ต์…”๋„ ๋ฐ”์ธ๋”ฉ์„ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด, ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ณต์žกํ•œ ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค์–ด์•ผํ•ฉ๋‹ˆ๋‹ค.

let students : [String?] = ["Mike", "Jane", nil, "John", nil]

let boostStudents = students.map({ student -> String? in
                                    if let name = student {
                                        return "BoostCamp2021-" + name
                                    } else{
                                        return nil
                                    }
})

print(boostStudents) // [Optional("BoostCamp2021-Mike"), Optional("BoostCamp2021-Jane"), nil, Optional("BoostCamp2021-John"), nil]

 

ํ•˜์ง€๋งŒ compactMap์„ ์‚ฌ์šฉํ•˜๋ฉด ์˜ต์…”๋„ ๋ฐ”์ธ๋”ฉ์„ ํ•˜๋ฉด์„œ ๋™์‹œ์— nil ๊ฐ’์„ ์ œ์™ธํ•œ ์ƒˆ๋กœ์šด ์ฝœ๋ ‰์…˜์„ ๋งŒ๋“ค์–ด๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋Œ€๋ฐ•!

let students : [String?] = ["Mike", "Jane", nil, "John", nil]
let boostStudents = students.compactMap({ $0 }).map( {"BoostCamp2021-" + $0})

print(boostStudents) // ["BoostCamp2021-Mike", "BoostCamp2021-Jane", "BoostCamp2021-John"]

FlatMap

FlatMap์€ 2์ฐจ์› ๋ฐฐ์—ด์— ๋‚˜๋ˆ„์–ด์ ธ์žˆ๋Š” ๋ฐ์ดํ„ฐ๋“ค์„ 1์ฐจ์› ๋ฐฐ์—ด๋กœ ํ•ฉ์ณ์ฃผ๋Š” ๊ธฐ๋Šฅ์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

let students = [["Mike", nil], [nil, nil, "Jane"], ["John"]]

๋จผ์ € ์œ„์™€ ๊ฐ™์€ ๋ฐฐ์—ด์„ 1์ฐจ์›์œผ๋กœ ๋งŒ๋“ค๊ณ  ์‹ถ๋‹ค๋ฉด, ๋‹ค์Œ์ฒ˜๋Ÿผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

let goodStudents = students.flatMap({$0})
print(goodStudents) // [Optional("Mike"), nil, nil, nil, Optional("Jane"), Optional("John")]

์•„์ง์€ ์˜ต์…”๋„ ๋ฐ”์ธ๋”ฉ์ด ์•ˆ๋˜์–ด ์žˆ๊ณ  nil์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์—ฌ๊ธฐ์„œ ์‹ค์ œ ์ด๋ฆ„๋“ค๋งŒ ๋ฝ‘์•„๋‚ด๊ณ  ์‹ถ๋‹ค๋ฉด compactMap๊ณผ ์—ฎ์–ด์„œ ์‚ฌ์šฉํ•˜๋ฉด ๋˜๊ฒ ์ฃ 

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

ForEach

forEach๋Š” for-in ๊ตฌ๋ฌธ์ฒ˜๋Ÿผ ์ฝœ๋ ‰์…˜์˜ ๊ฐ ์š”์†Œ๋“ค์„ ๋ฝ‘์•„๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. for-in ๊ณผ๋Š” ๋‹ค๋ฅด๊ฒŒ ๊ณ ์ฐจํ•จ์ˆ˜์— ํฌํ•จ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ธ€๋กœ๋ฒŒ ์Šค์ฝ”ํ”„์—์„œ ์‚ฌ์šฉํ–ˆ์„ ๋•Œ๋„ return ์„ ํ†ตํ•ด ํ˜„์žฌ ๋ฐ˜๋ณต์„ ์ข…๋ฃŒํ•˜๊ณ  ๋‹ค์Œ ๋ฐ˜๋ณต์œผ๋กœ ์ด์–ด๋‚˜๊ฐˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งˆ์น˜ continue์ฒ˜๋Ÿผ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. forEach๋Š” ๋‹ค๋ฅธ ๊ณ ์ฐจํ•จ์ˆ˜์ฒ˜๋Ÿผ ์ƒˆ๋กœ์šด ์ฝœ๋ ‰์…˜์ด๋‚˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋‹จ์ˆœํ•œ ์ˆœํšŒ์˜ ์šฉ๋„๋กœ ์‚ฌ์šฉํ•˜๊ธฐ์— ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค.

let numbers = [1, 2, 3, 4, 5]
numbers.forEach({
    print($0)
})

//1
//2
//3
//4
//5

 

๊ณ ์ฐจํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ฝ”๋“œ ๊ฐ€๋…์„ฑ์ด ์•„์ฃผ์•„์ฃผ ์ข‹์•„์ง€๊ณ , ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํŠน์œ ์˜ ์ซ„๊นƒํ•จ(?)์„ ๋Š๋‚„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค..! ์†์— ์ต๊ฒŒ ๊ธฐํšŒ๊ฐ€ ๋  ๋•Œ๋งˆ๋‹ค ์ž์ฃผ ์‚ฌ์šฉํ•ด๋ด์•ผ๊ฒ ์–ด์š”! ๋ฌด์ง€์„ฑ for ๊ธˆ์ง€!