-
Notifications
You must be signed in to change notification settings - Fork 0
Closed
Description
💬 문제
💬 Idea
-
HEAD와 NUMBER를 구분해주기
- HEAD : 숫자가 아닌 첫 부분을 반환. 이 때 HEAD 부분의 대소문자는 정렬 시 구분이 되지 않아도 되므로 lowercased()를 적용해준다.
- NUMBER : 숫자가 아닌 부분을 건너띄고 숫자부터 ~ 다시 문자가 나오는 부분까지를 반환
- TAIL: 나머지 // 이 부분은 문제 풀이에 큰 상관이 없기에 따로 구하지 않아도 된다.
-
HEAD값을 key값으로 하여 Dictionary에 (NUMBER, ORIGINALFILE, index) 를 값으로 저장해준다. // 숫자, 기존 파일명, 들어온 순서
-
정렬하기
- HEAD값이 같은 파일명이 존재할 때 → values에 여러 값이 저장되기 때문에 딕셔너리를 key값으로 우선 정렬한 후 value 값을 돌며 조건대로 숫자순, 들어온 순 정렬을 하는 로직
💬 풀이
func solution(_ files:[String]) -> [String] {
var headNumberDict: [String: [(Int, String, Int)]] = [:]
var res: [String] = []
for (index, file) in files.enumerated() {
let HEAD = file.prefix{ !$0.isNumber }.lowercased()
let NUMBER = file.drop { !$0.isNumber }.prefix(while: { $0.isNumber })
if headNumberDict[HEAD] != nil {
headNumberDict[HEAD]?.append((Int(NUMBER) ?? 0, file, index))
} else {
headNumberDict[HEAD] = [(Int(NUMBER) ?? 0, file, index)]
}
}
for i in headNumberDict.sorted(by: { $0.key < $1.key }) {
let s = i.value.sorted(by: { $0.0 == $1.0 ? $0.2 < $1.2 : $0.0 < $1.0 })
for j in s {
res.append(j.1)
}
}
return res
}
💬 더 나은 방법?
- 딕셔너리를 사용하고도 sorted(by: )를 사용할 것이면
- 딕셔너리를 사용하지 않고 배열을 사용하여 한번에 sorted(by: ) 에서 조건을 주어 사용자 지정 정렬을 해줄 수 있다.
→ 2중 for문을 사용하지 않아도 되어 코드도 효율적이고 훨씬 깔끔하다.
func solution(files:[String]) -> [String] {
var arr: [(String, Int, Int, String)] = []
var res: [String] = []
for (index, file) in files.enumerated() {
let HEAD = file.prefix{ !$0.isNumber }.lowercased()
let NUMBER = file.drop{ !$0.isNumber }.prefix(while: { $0.isNumber }).prefix(5)
arr.append((HEAD, Int(NUMBER) ?? 0, index, file))
}
arr = arr.sorted(by: {
if $0.0 != $1.0 { return $0.0 < $1.0 }
if $0.1 != $1.1 { return $0.1 < $1.1 }
return $0.2 < $1.2
})
for i in arr {
res.append(i.3)
}
return res
}
💬 알게된 문법
✅ drop(while:)
주어진 조건자를 건너띈 첫번째 시퀀스부터 반환합니다.
let numbers = [3, 7, 4, -2, 9, -6, 10, 1]
let startingWithNegative = numbers.drop(while: { $0 > 0 })
// startingWithNegative == [-2, 9, -6, 10, 1]