문제 설명
문자열 s에는 공백으로 구분된 숫자들이 저장되어 있습니다. str에 나타나는 숫자 중 최소값과 최대값을 찾아 이를 "(최소값) (최대값)"형태의 문자열을 반환하는 함수, solution을 완성하세요.
예를들어 s가 "1 2 3 4"라면 "1 4"를 리턴하고, "-1 -2 -3 -4"라면 "-4 -1"을 리턴하면 됩니다.
첫 풀이
import Foundation
class Solve {
func solution(_ s: String) -> String {
let arr = s.split(separator: " ")
return "\(arr.min()!) \(arr.max()!)" }}
let solution = Solve()
print(solution.solution("-1 -2 -3 -4"))
실패
["-1 -2 -3 -4"]가 인자값으로 들어왔을 때 -4 , -1 이 아니라 -1 -4 가 출력된다.
arr.min()
을 -4 보다 -1을 더 작은 값으로 인식하네? 절댓값으로 판단해주나 ?
print((-4 ... -1).min()!)
-1이 찍혀야하는데, -4가 잘 출력되는 것을 확인할 수 있다.
결국,이게 절댓값으로 판단하지는 않는 것 같고 배열안 숫자들을 문자열로 인식하고 있기 때문임을 알아냈다.
ARRAY : ["-1", "-2", "-3", "-4"]
-1 -4
이런식으로 찍히는 걸 보아하니 배열안 원소값들이 전부 문자열로 되어있어서 사전식으로 판단을 해준 것 같다.
-> 결론은 이제 이걸 숫자값으로 비교가 되게끔 유도하면 되는 것을 알았다.
class Solve {
func solution(_ s: String) -> String {
let arr = s.split(separator: " ")
print("ARRAY : \(arr)")
return "\(arr.min()!) \(arr.max()!)"
}
}
let solution = Solve()
print(solution.solution("-1 -2 -3 -4"))
- 처음 가공된 배열을 전부 Int로 바꿔주기
이때는compactMap
이라는 함수사용해서 해주면 된다고 한다.
처음에는 map
써서 해주려고 했는데,
주어진 클로저를 시퀀스의 요소에 매핑한 결과를 포함하는 배열을 반환합니다
let arr = s.split(separator: " ").map { Int($0) }
이렇게 사용해줬을 때
ARRAY : [Optional(-1), Optional(-2), Optional(-3), Optional(-4)]
이런식으로 Optional한 배열로 반환이 된다.
물론 map { Int($0)! }
이런식으로 강제 언래핑을 통해서 Optional이 아닌값으로 잘 출력을 할 수 있지만 이럴때는 갑자기 “a”같이 숫자가 아닌값이 포함되어있으면 프로그램이 터져버릴 것이다.
- 변환 과정에서 nil 값을 필터링하기 때문에 결과 배열에는 nil이 포함되지 않는 것이고,
- 옵셔널 값을 제거하고 실제 값을 반환한다.
let arr = s.split(separator: " ").compactMap { Int($0) }
이렇게 사용해준다면 강제언래핑도 필요없고, 반환이 실패한 값은 nil로 필터링을 해주기 때문에 프로그램 충돌걱정도 없다. ["1", "a", "3"]
-> [1, 3]
또한 Optional값으로 돌려주지 않기때문에 쉽게 활용이 가능하다는 장점이 있다.
func solution(_ s: String) -> String {
let arr = s.split(separator: " ").compactMap { Int($0) }
return "\(arr.min()!) \(arr.max()!)"
}
- min,max에 by인자로 Int값 비교해주게하기
단순히 min() , max() 써서 알아서 지정된 사전식,숫자면 크기 비교를 수행할 수도 있지만,
(by:)인자를 활용하여 원하는 조건대로 판단하게 할 수 있다.
이때는 Int()를 통해서 각 원소들을 비교해서 사전식으로 대소관계를 판단하지 않게끔 유도했다. 이전에도 언급했듯이 Int()는 optional 함수이기 대문에 강제언래핑은 필수다 !
func solution(_ s: String) -> String {
let arr = s.split(separator: " ")
print("ARRAY : \(arr)")
return "\(arr.min(by: { Int($0)! < Int($1)! })!) \(arr.max { Int($0)! < Int($1)! }!)"
}