λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°

🍎 iOS/Swift

[Swift] κ³ μ°¨ν•¨μˆ˜ - map, filter, reduce

μ•ˆλ…•ν•˜μ„Έμš” μ œμΈμž…λ‹ˆλ‹€!

μ˜€λŠ˜μ€ Swift의 κ³ μ°¨ν•¨μˆ˜ λŒ€ν•΄ μ•Œμ•„λ³΄λ €κ³  ν•©λ‹ˆλ‹€.

Swift의 μ—¬λŸ¬κ°€μ§€ κ³ μ°¨ν•¨μˆ˜ 쀑 κ°€μž₯ 자주 쓰이고, μ•Œκ³ λ¦¬μ¦˜ 문제 풀이 μ‹œμ—λ„ μœ μš©ν•˜κ²Œ μ‚¬μš©λ˜λŠ”

map, filter, reduce μš” 세가지 ν•¨μˆ˜μ— λŒ€ν•΄ 정리해보도둝 ν•˜κ² μŠ΅λ‹ˆλ‹€!

κ³ μ°¨ν•¨μˆ˜λž€?

κ³ μ°¨ν•¨μˆ˜λŠ” λ‹€λ₯Έν•¨μˆ˜λ₯Ό μ „λ‹¬μΈμžλ‘œ λ°›κ±°λ‚˜ ν•¨μˆ˜λ₯Ό 결과둜 λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜λ₯Ό λ§ν•©λ‹ˆλ‹€.

(SwiftλŠ” ν•¨μˆ˜λ₯Ό 일급 객체둜 μ·¨κΈ‰ν•˜κΈ° λ•Œλ¬Έμ— ν•¨μˆ˜λ₯Ό λ‹€λ₯Έ ν•¨μˆ˜μ˜ μ „λ‹¬μΈμžλ‘œ μ‚¬μš©ν•˜κ±°λ‚˜ ν•¨μˆ˜λ₯Ό 결과둜 λ°˜ν™˜ν•˜λŠ” 것이 κ°€λŠ₯ν•©λ‹ˆλ‹€!)

κ³ μ°¨ν•¨μˆ˜μ˜ μ’…λ₯˜λ‘œλŠ” map, filter, reduce, forEach, compactMap, flatMap 등이 μžˆμŠ΅λ‹ˆλ‹€.

이 μ€‘μ—μ„œ κ°€μž₯ λŒ€ν‘œμ μœΌλ‘œ 많이 μ‚¬μš©λ˜λŠ” map, filter, reduce에 λŒ€ν•΄ μžμ„Ένžˆ μ•Œμ•„λ΄…μ‹œλ‹€!

map

map은 μžμ‹ μ„ ν˜ΈμΆœν•  λ•Œ λ§€κ°œλ³€μˆ˜λ‘œ μ „λ‹¬λœ ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν•˜μ—¬ κ·Έ κ²°κ³Όλ₯Ό λ‹€μ‹œ λ°˜ν™˜ν•΄μ£ΌλŠ” ν•¨μˆ˜μž…λ‹ˆλ‹€.

μ’€ 더 ν’€μ–΄μ„œ μ„€λͺ…ν•˜μžλ©΄, 맡을 μ‚¬μš©ν•˜λ©΄ μ»¨ν…Œμ΄λ„ˆκ°€ λ‹΄κ³  있던 각각의 값을 λ§€κ°œλ³€μˆ˜λ₯Ό 톡해 받은 ν•¨μˆ˜μ— μ μš©ν•œ ν›„,

λ‹€μ‹œ μ»¨ν…Œμ΄λ„ˆμ— 포μž₯ν•˜μ—¬ λ°˜ν™˜ν•©λ‹ˆλ‹€. 이 λ•Œ, κΈ°μ‘΄ μ»¨ν…Œμ΄λ„ˆμ˜ 값은 λ³€κ²½λ˜μ§€ μ•Šκ³  μƒˆλ‘œμš΄ μ»¨ν…Œμ΄λ„ˆκ°€ μƒμ„±λ˜μ–΄ λ°˜ν™˜λ©λ‹ˆλ‹€.

κ·Έλ ‡κΈ° λ•Œλ¬Έμ— map은 κΈ°μ‘΄ 데이터λ₯Ό λ³€ν˜•(transform)ν•˜λŠ” 데 많이 μ‚¬μš©λ©λ‹ˆλ‹€.

 

κ³΅μ‹λ¬Έμ„œμ—λŠ” λ‹€μŒκ³Ό 같이 μ •μ˜λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.

transformμ΄λΌλŠ” 맀핑 ν΄λ‘œμ € ν˜•νƒœμ˜ λ§€κ°œλ³€μˆ˜λ₯Ό 가지고 있고, 이 ν΄λ‘œμ €λŠ” μ»¨ν…Œμ΄λ„ˆμ˜ μš”μ†Œλ₯Ό λ§€κ°œλ³€μˆ˜λ‘œ λ°›μ•„ 값을 λ³€ν™˜ν•΄ λ°˜ν™˜ν•©λ‹ˆλ‹€.

그리고 ν΄λ‘œμ €λ₯Ό ν†΅ν•΄μ„œ λ³€ν™˜λœ μš”μ†Œλ₯Ό ν¬ν•¨ν•˜λŠ” 배열을 μ΅œμ’…μ μœΌλ‘œ λ°˜ν™˜ν•˜κ³  μžˆλŠ” 것을 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.

이제 ꡬ체적인 μ½”λ“œ μ˜ˆμ‹œλ₯Ό 톡해 μ™„λ²½νžˆ μ΄ν•΄ν•΄λ΄…μ‹œλ‹€!!

 

// numbers의 각 μš”μ†Œμ— 2 κ³±ν•˜κΈ°

// map μ‚¬μš©
let numbers = [1, 2, 3, 4]
let doubledNumbers: [Int] = numbers.map { $0 * 2 }

print(doubledNumbers) // [2, 4, 6, 8]

// for 반볡문 μ‚¬μš©
let numbers = [1, 2, 3, 4]
let doubledNumbers: [Int] = []

for i in numbers {
    doubledNumbers.append(i * 2)
}

print(doubledNumbers) // [2, 4, 6, 8]

 

μœ„μ˜ μ½”λ“œλŠ” λ°°μ—΄μ˜ 각 μš”μ†Œμ— 2λ₯Ό κ³±ν•œ 값을 λ°˜ν™˜ν•˜λŠ” κ°„λ‹¨ν•œ μ˜ˆμ‹œμž…λ‹ˆλ‹€.

이 μž‘μ—…μ€ for λ°˜λ³΅λ¬Έμ„ μ΄μš©ν•΄μ„œλ„ μ²˜λ¦¬ν•  수 μžˆλŠ”λ°μš”,

map은 μ»¨ν…Œμ΄λ„ˆ μš”μ†Œλ₯Ό λ§€κ°œλ³€μˆ˜λ‘œ λ°›μ•„ ν΄λ‘œμ €μ—μ„œ μ—°μ‚°μœΌλ‘œ μ²˜λ¦¬ν•˜μ—¬ λ³€ν™˜λœ 값을 λ°”λ‘œ μƒˆλ‘œμš΄ μ»¨ν…Œμ΄λ„ˆλ‘œ λ°˜ν™˜ν•˜κΈ° λ•Œλ¬Έμ—

λ³΅μž‘ν•œ μ—°μ‚°μΌμˆ˜λ‘ map을 μ‚¬μš©ν•˜λŠ” 것이 for문을 μ‚¬μš©ν•˜λŠ” κ²½μš°λ³΄λ‹€ 훨씬 더 κ°„κ²°ν•˜κ²Œ ν‘œν˜„μ΄ κ°€λŠ₯ν•©λ‹ˆλ‹€!

filter

filterλŠ” ν•¨μˆ˜ μ΄λ¦„μœΌλ‘œλ„ μ§κ΄€μ μœΌλ‘œ μ•Œ 수 μžˆλ“―μ΄ μ»¨ν…Œμ΄λ„ˆ λ‚΄λΆ€μ˜ 값을 κ±ΈλŸ¬μ„œ μΆ”μΆœν•˜λŠ” 역할을 ν•˜λŠ” κ³ μ°¨ν•¨μˆ˜μž…λ‹ˆλ‹€.

κ·Έλ ‡κΈ° λ•Œλ¬Έμ— νŠΉμ • 쑰건에 맞게 값을 κ±ΈλŸ¬λ‚΄κ³  싢을 λ•Œ 많이 μ‚¬μš©λ˜κ² μ£ ??

filter도 mapκ³Ό λ§ˆμ°¬κ°€μ§€λ‘œ μƒˆλ‘œμš΄ μ»¨ν…Œμ΄λ„ˆμ— 값을 λ‹΄μ•„ λ°˜ν™˜ν•΄μ€λ‹ˆλ‹€.

 

κ³΅μ‹λ¬Έμ„œμ—λŠ” λ‹€μŒκ³Ό 같이 μ •μ˜λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.

 

filter ν•¨μˆ˜μ˜ λ§€κ°œλ³€μˆ˜λ‘œ μ „λ‹¬λ˜λŠ” isIncludedλΌλŠ” ν΄λ‘œμ €λŠ” Bool νƒ€μž…μ˜ 값을 λ°˜ν™˜ν•©λ‹ˆλ‹€.

이 ν΄λ‘œμ €λŠ” μ»¨ν…Œμ΄λ„ˆμ˜ μš”μ†Œλ₯Ό 인자둜 λ°›μ•„ μš”μ†Œκ°€ μ΅œμ’…μ μœΌλ‘œ λ°˜ν™˜λ  μƒˆλ‘œμš΄ μ»¨ν…Œμ΄λ„ˆμ— 포함될 ν•­λͺ©μ΄λΌκ³  νŒλ‹¨ν•˜λ©΄ trueλ₯Ό, μ•„λ‹ˆλΌλ©΄ falseλ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€. μ½”λ“œ μ˜ˆμ‹œλ‘œ 더 μ‚΄νŽ΄λ΄…μ‹œλ‹€!!

 

// numbersμ—μ„œ 짝수만 μΆ”μΆœ

// filter μ‚¬μš©
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
let evenNumbers = numbers.filter { $0 % 2 == 0 }

print(evenNumbers) // [2, 4, 6, 8]

// for 반볡문 μ‚¬μš©
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
var evenNumbers: [Int] = []

for number in numbers {
    if number % 2 == 0 {
        evenNumbers.append(number)
    }
}

print(evenNumbers) // [2, 4, 6, 8]

 

μœ„μ˜ μ½”λ“œλŠ” κΈ°μ‘΄ λ°°μ—΄μ—μ„œ 짝수만 μΆ”μΆœν•˜λŠ” 연산을 ν•˜λŠ” κ°„λ‹¨ν•œ μ˜ˆμ‹œμž…λ‹ˆλ‹€.

filter ν•¨μˆ˜μ˜ μ˜ˆμ‹œλ„ for λ°˜λ³΅λ¬Έμ„ μ‚¬μš©ν•œ μ˜ˆμ‹œμ™€ 비ꡐλ₯Ό ν•΄λ³΄μ•˜λŠ”λ°μš”, 

for문으둜 배열을 μˆœνšŒν•˜λ©° 쑰건(짝수인 μš”μ†Œ)에 λ§žλŠ” μš”μ†Œλ“€μ„ μƒˆλ‘œμš΄ 배열에 ν•˜λ‚˜μ”© append ν•΄μ£ΌλŠ” 과정을 

filter둜 보닀 쉽고 κ°„λ‹¨ν•˜κ²Œ μ²˜λ¦¬ν•  수 μžˆλ‹€λŠ” 것을 확인할 수 μžˆμŠ΅λ‹ˆλ‹€!

reduce

reduceλŠ” μ»¨ν…Œμ΄λ„ˆ λ‚΄λΆ€μ˜ μš”μ†Œλ“€μ„ ν•˜λ‚˜λ‘œ ν•©ν•˜λŠ” κΈ°λŠ₯을 μ‹€ν–‰ν•˜λŠ” κ³ μ°¨ν•¨μˆ˜μž…λ‹ˆλ‹€.

 

λ°”λ‘œ κ³΅μ‹λ¬Έμ„œλ₯Ό 확인해보면, λ‹€μŒκ³Ό 같이 μ •μ˜λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.

 

μœ„μ—μ„œ μ‚΄νŽ΄λ³Έ map, filter와 달리 λ§€κ°œλ³€μˆ˜λ‘œ λ°›λŠ” ν΄λ‘œμ €κ°€ 두 개 μž…λ‹ˆλ‹€!

첫 번째 λ§€κ°œλ³€μˆ˜μΈ initialResultλΌλŠ” μ΄λ¦„μ˜ ν΄λ‘œμ €λ‘œ μ „λ‹¬λ˜λŠ” 값을 ν†΅ν•΄μ„œ μ΄ˆκΉƒκ°’μ„ 지정해쀄 수 μžˆμŠ΅λ‹ˆλ‹€.

두 번째 λ§€κ°œλ³€μˆ˜μΈ nextPartialResultλΌλŠ” μ΄λ¦„μ˜ ν΄λ‘œμ €λŠ” λ§€κ°œλ³€μˆ˜λ₯Ό 두 개 κ°€μ§€λŠ”λ°,

첫 번째 λ§€κ°œλ³€μˆ˜λŠ” initialResult λ§€κ°œλ³€μˆ˜λ₯Ό 톡해 전달받은 μ΄ˆκΉƒκ°’ λ˜λŠ” 이전 ν΄λ‘œμ €μ˜ κ²°κ΄κ°’μž…λ‹ˆλ‹€. μ΄λŠ” λͺ¨λ“  μˆœνšŒκ°€ 끝날 경우, reduce ν•¨μˆ˜μ˜ μ΅œμ’… 결괏값이 λ©λ‹ˆλ‹€.

두 번째 λ§€κ°œλ³€μˆ˜λŠ” reduce ν•¨μˆ˜κ°€ ν˜„μž¬ μˆœνšŒν•˜κ³  μžˆλŠ” μ»¨ν…Œμ΄λ„ˆμ˜ μš”μ†Œμž…λ‹ˆλ‹€.

μ„€λͺ…λ§ŒμœΌλ‘œ 이해가 쑰금 μ–΄λ €μšΈ 수 μžˆλŠ”λ°, μ˜ˆμ‹œ μ½”λ“œλ₯Ό ν†΅ν•΄μ„œ 더 μ‚΄νŽ΄λ΄…μ‹œλ‹€!

 

// 각 μš”μ†Œμ˜ ν•© κ΅¬ν•˜κΈ°

// reduce μ‚¬μš©
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let sum = numbers.reduce(0) { $0 + $1 }

print(sum) // 55

// for 반볡문 μ‚¬μš©
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
var sum = 0

for number in numbers {
    sum += number
}

print(sum) // 55

 

μœ„μ˜ μ˜ˆμ‹œμ½”λ“œλŠ” numbers λ°°μ—΄μ˜ λͺ¨λ“  μš”μ†Œμ˜ 합을 κ΅¬ν•˜λŠ” κ°„λ‹¨ν•œ μ˜ˆμ œμž…λ‹ˆλ‹€.

μ•žμ˜ μ˜ˆμ‹œλ“€κ³Ό λ§ˆμ°¬κ°€μ§€λ‘œ for 반볡문으둜 배열을 μˆœνšŒν•˜λ©΄μ„œ 합을 κ΅¬ν•˜λŠ” κ²½μš°μ™€ λΉ„κ΅ν•΄λ³΄μ•˜λŠ”λ°μš”, 훨씬 더 ν‘œν˜„μ‹μ΄ κ°„λ‹¨ν•΄μ§€λŠ” 것을 확인할 수 있죠??

reduce μ‚¬μš© μ˜ˆμ‹œ μ½”λ“œλ₯Ό 보면, 0을 μ΄ˆκΉƒκ°’μœΌλ‘œ 가지고 μ»¨ν…Œμ΄λ„ˆλ₯Ό μˆœνšŒν•˜λ©° μ΄μ „μ˜ 값에 계속 μš”μ†Œλ“€μ„ 더해 μ΅œμ’… 결괏값을 λ°˜ν™˜ν•˜λŠ” 것을 μ•Œ 수 μžˆμŠ΅λ‹ˆλ‹€.

$0μ—λŠ” μ²˜μŒμ— μ΄ˆκΉƒκ°’μΈ 0이 μ „λ‹¬λ˜κ³ , 0λΆ€ν„° μΆœλ°œν•΄ λ§ˆμ§€λ§‰ μš”μ†ŒκΉŒμ§€ μˆœνšŒν•˜λŠ” λ‚΄λ‚΄μ˜ 결괏값이 λ©λ‹ˆλ‹€.

$1은 ν˜„μž¬ μˆœνšŒν•˜κ³  μžˆλŠ” μš”μ†Œμ˜ κ°’μž…λ‹ˆλ‹€. κ·Έλ ‡κΈ° λ•Œλ¬Έμ— $0(λˆ„μ ν•©κ³„)에 $1(ν˜„μž¬ μš”μ†Œ)을 λ”ν•œ 값이 μ΅œμ’… λ°˜ν™˜ 값이 λ˜λŠ” κ²ƒμž…λ‹ˆλ‹€!

 

 

μ΄λ ‡κ²Œ Swift의 λŒ€ν‘œμ μΈ κ³ μ°¨ν•¨μˆ˜ 3가지λ₯Ό μ •λ¦¬ν•΄λ³΄μ•˜λŠ”λ°μš”!

κ³ μ°¨ν•¨μˆ˜λ₯Ό 잘 ν™œμš©ν•˜λ©΄ κΈ°μ‘΄ 쑰건문, 반볡문 λ“±μœΌλ‘œ μ²˜λ¦¬ν–ˆλ˜ μ½”λ“œλŠ” κ°„κ²°ν•˜κ²Œ μ€„μ΄λŠ” 것이 κ°€λŠ₯ν•  것 κ°™μŠ΅λ‹ˆλ‹€.

μ•Œκ³ λ¦¬μ¦˜ 문제 풀이에도 μœ μš©ν•˜κ²Œ ν™œμš©λ˜λ‹ˆ 잘 정리해두면 쒋을 것 κ°™μŠ΅λ‹ˆλ‹€!!😊😊

 


[참고 자료]

 

<Apple 곡식 λ¬Έμ„œ>

https://developer.apple.com/documentation/swift/array/map(_:)-87c4d 

https://developer.apple.com/documentation/swift/sequence/filter(_:) 

https://developer.apple.com/documentation/swift/array/reduce(_:_:) 

 

<μŠ€μœ„ν”„νŠΈ ν”„λ‘œκ·Έλž˜λ°: Swift 5>

https://product.kyobobook.co.kr/detail/S000001810190