문제 설명
정수를 담고 있는 배열 arr의 평균값을 return하는 함수, solution을 완성해보세요.
제한사항
입출력 예
arr | return |
---|---|
[1,2,3,4] | 2.5 |
[5,5] | 5 |
풀이 과정
이번에도 평균 구하기!
지난번 배열의 평균값 문제랑 같더라.
그래서 해결은 금방 했지만, 다른 풀이 방식을 더 공부해보기로 했다.
“평균값 = 모든 수를 더한 총합을 총 개수로 나눈 값” 이므로
1. for ~ in 구문 사용해 arr 배열의 원소의 합을 구하고,
2. count를 사용해 배열의 길이(배열 내 원소의 개수)를 구해
1에서 2를 나눠주었다.
Solution
func solution(_ arr:[Int]) -> Double {
var sum = 0
for i in arr {
sum += i
}
return Double(sum) / Double(arr.count)
}
Another Solution
합을 구하는 문제를 풀 때 마다 보았던 풀이 방식들 중 하나가
Swift의 고차함수인 reduce를 사용하는 것이었다.
일단 고차함수 개념부터 알아보자
고차함수
📎 Map
다른 함수를 전달이자로 받거나, 함수의 실행 결과를 함수로 반환하는 함수
대표적인 고차함수에는 map, filter, reduce 가 있다.특정 컨테이너의 데이터를 변형해서 새로운 배열로 만들어서 리턴해주는 메소드.
새로운 컨테이너를 만들기 때문에 기존 데이터는 변형되지 않는다.//example let numbers = [1, 2, 3, 4, 5] var plusOne = [] //클로저 생략하지 않고 표현 plusOne = numbers.map({ (number : Int) -> Int in return number + 1 }) //생략 표현을 해주면 $ 사인 활용해 인자 인덱스 표현(아래 클로저 단축인자 개념 참고) let numbersPlusOne = numbers.map({ $0 + 1 })
📎 Filter콜렉션 내부에서 조건에 맞는 데이터들만 골라 새로운 콜렉션을 생성한다.
filter 메소드는 클로저를 인자로 받고, 이 클로저 내부에 어떤 데이터를 포함시킬 지 그 조건을 정의한다.//example let numbers: [Int] = [1, 2, 3, 4, 5, 6] var isEven: [Int] = [] //클로저 생략하지 않고 표현 isEven = numbers.filter({ (number: Int) -> Int in return number % 2 == 0 //짝수 //생략 표현 var isEven = numbers.filter { $0 % 2 == 0 } //[2, 4, 6]
📎 Reduce콜렉션 내부의 데이터들을 하나로 통합시킨다.
두 개의 인자를 받는다. 첫 번째 인자는 통합할 데이터의 초기값, 두 번째 인자는 클로저이다.
이 클로저에서는 값을 어떻게 통합할 것인지 정의한다. 두 개의 파라미터가 사용되는데, 첫 번째는 바로 이전 값에 대한 통합된 데이터, 두 번째는 새로 통합할 데이터를 의미한다.
간단하게 말하자면 인자들을 차례로 돌면서 연산을 전부 해서 하나의 값을 리턴한다고 생각하면 된다.👉 추가 개념 공부 **Closure 클로저** 함수와 함수가 선언된 어휘적 환경의 조합, 일정 기능을 하는 코드를 하나의 블록으로 모아놓은 것으로 Named Closure 와 Unnamed Closure 두 종류가 있다. 보통 Unnamed Closure(익명함수)를 지칭하는 경우가 많다.//example let sum : Int = numbers.reduce(0, { (first: Int, second: Int) -> Int in print("\(first) + \(second)") return first + second }) //example2 let minus: Int = numbers.reduce(100) { $0 - $1 } print(sum) // 0 + 1 // 1 + 2 // 3 + 3 // 6 + 4 // 10 + 5 // return 15 Print(minus) //85
//Name Closure func doSomething() { print("Something") } //Unnamed Closure let closure = { print("Something") } //Unnamed Closure 표현식 { (Parameters//(Closure Head)) -> return type in 실행구문//(Closure Body)
클로저의 단축인자 이름
첫 번째 전달인자부터 $0, $1, $2…를 이용해 생략 가능하고,
키워드 ‘in’도 생략 가능하다(매개변수/반환타입을 실행코드와 구분하기 위해 사용하는 것이기 때문에)
아래는 Reduce 와 클로저 개념을 이해하고 이번 문제에 적용한 풀이.
func solution(_ arr:[Int]) -> Double {
return Double (arr.reduce(0, { $0 + $1 })) / Double(arr.count)
//
func solution(_ arr:[Int]) -> Double {
return Double (arr.reduce((통합될데이터의초기값), { $0 + $1 })) / Double(arr.count)
참고 자료
https://ios-developer-storage.tistory.com/entry/Swift-고차함수-map-filter-reduce를-완전-쉽게-알아보자