Swift

Swift :: 고차함수 -Map, Filter, Reduce 알아보기

상어(shark) 2019. 2. 7. 19:15

안녕하세요! 상어입니다.

이번편에서는 대표적인 고차함수인 map, filter, reduce에 대해 알아보고자 해요.

배열을 내 마음대로 볶고 지질때 이애들은 필수필수이죳!


이애들이 무슨 애들인지 궁금하고 설레지않나요?!

네 전 설레요 헤헤헿 

그럼 얼릉 알아보러 출바알~😎



고차함수

먼저, 고차함수에 대해 알아볼까요?

고차함수는 다른 함수를 전달인자로 받거나 함수실행의 결과를 함수로 반환하는 함수를 뜻합니다.


네.. 좋은 뜻입니다....

사실 이해가 잘 안됬어욬ㅋㅋㅋ 그래서 저는

스위프트 라이브러리에서 제공하는 유용한 고차함수인 map, filter, reduce의 예시를 통해 더더 이해해보도록 하겠습니다 :-)



Map(변형)


map은 데이터를 변형하고자 할 때 사용합니다.

기존 데이터를 변형하여 새로운 컨테이너를 만드는데, 기존 데이터는 변형되지 않습니다.

특히 map은 기존의 for-in 구문과 큰 차이가 없지만, map 사용시 다음과 같은 이점이 있습니다.

  • 코드의 간결성
  • 재사용 용이
  • 컴파일러 최적화 성능 좋음
차이점은 눈으로 봤을 때 가장 빨리 보이기 때문에 다음 예제를 살펴보겠습니다.

하기 전에 map의 기본 형태를 보자면
array.map(transform: T throws -> T)
입니다. T타입의 transform을 받아 새로운 T타입의 컨테이너를 생성한다는 이야기지용!
그럼 형태를 파악했으니 이제 진짜진짜 어떻게 사용하는지 파악해볼까요?!

* for-in

let numArray = [1,3,5,7,9]
var multiArray = [Int]()

for num in numArray {
    multiArray.append(num * 2)
}

print(multiArray)
// [2, 6, 10, 14, 18]

* map

let numArray = [1,3,5,7,9] let multiArray = numArray.map { $0 * 2 } print(multiArray) // [2, 6, 10, 14, 18]


어떤가욤, 코드가 확 짧아졌다는게 느껴지시나요?

지금은 제가 간단한 예제를 가져왔기에 전혀 아닌데?!! 라고 하실 수 있지만, 점점 더 많은 연산과 다양한 조건이 들어가면 for-in보다 map이 간결하고 편하다는 것을 느끼실 수 있으실 거에요.


그리고 현재 map의 코드는 

let numArray = [1,3,5,7,9] let multiArray = numArray.map({ (number: Int) -> Int in return number * 2 }) print(multiArray) // [2, 6, 10, 14, 18]

위 코드에서 매개변수, 반환 타입, 반환 키워드(return)를 생략(축약)한 후행 클로저 입니다. 바로 이해가 안되시는 분들은 위의 코드를 보시고 저렇게 많은 것을 생략할 수 있다는 것을 알아두신다면 편할 것 같아요~ :)



Filter(추출)


filter는 데이터를 추출하고자 할 때 사용합니다.

기존 컨테이너에서 내부의 값을 걸러 새로운 컨테이너를 만듭니다.

filter 또한 map과 마찬가지로 for-in문과 크게 다르지 않습니다.


우선, filter의 기본 형태를 보면

array.filter(isIncluded: T throws -> T)

T타입의 isIncluded를 받아 새로운 T형태의 컨테이너를 생성합니다.


* for-in

let stringAttay = ["가수", "대통령", "개발자", "선생님", "의사", "검사", "건물주"]
var threeCountArray = [String]()

for st in stringAttay {
    if st.count == 3 {
        threeCountArray.append(st)
    }
}

print(threeCountArray)
// ["대통령", "개발자", "선생님", "건물주"]

* filter

let stringAttay = ["가수", "대통령", "개발자", "선생님", "의사", "검사", "건물주"]
let threeCountArray = stringAttay.filter { $0.count == 3 }

print(threeCountArray)
// ["대통령", "개발자", "선생님", "건물주"]

위 코드는 map의 예제와 마찬가지로 아래의 코드에서 매개변수, 반환 타입, 반환 키워드(return)를 생략한 후행 클로저 입니다. 

let stringAttay = ["가수", "대통령", "개발자", "선생님", "의사", "검사", "건물주"]
let threeCountArray = stringAttay.filter({ (value: String) -> Bool in
    return value.count == 3
})

print(threeCountArray)
// ["대통령", "개발자", "선생님", "건물주"]



Reduce(결합)


reduce는 데이터를 합쳐주기 위해 사용합니다.

기존 컨테이너에서 내부의 값들을 결합하여 새로운 값을 만듭니다.


reduce를 한번에 이해하기엔 숫자 합 예제가 최고라 저 또한 합 예제를 만들어보았습니답~ 히히


* for-in

let numberArray = [1,2,3,4,5,6,7,8,9,10]
var sum = 0

for number in numberArray {
    sum += number
}

print(sum)
// 55

* reduce

let numberArray = [1,2,3,4,5,6,7,8,9,10]
let sum = numberArray.reduce(0) { $0 + $1 }

print(sum)
// 55

위 코드는 map의 예제와 마찬가지로 아래의 코드에서 매개변수, 반환 타입, 반환 키워드(return)를 생략한 후행 클로저 입니다.

let numberArray = [1,2,3,4,5,6,7,8,9,10]
let sum = numberArray.reduce(0, { (first: Int, second: Int) -> Int in
    return first + second
})

print(sum)
// 55


이처럼, stream문법을 잘 활용하게 된다면 코드를 짧게 짤수있어서 좋은것 같아요.

간단하게 map, filter, reduce에 대해 작성해봤는데 이해가 잘 되셨으면 좋겠어욯ㅎㅎ

그럼 우리 모두 stream문법을 기똥하게 사용할 수 있는 그날이 오길 바라며...!!


안뇽!