@@ -18,19 +18,39 @@ extension Array where Element == URL {
1818 /// Sorts the elements in alphabetical order.
1919 /// - Parameter foldersOnTop: if set to `true` folders will always be on top of files.
2020 /// - Returns: A sorted array of `URL`
21- func sortItems( foldersOnTop: Bool ) -> Self {
22- var alphabetically = sorted { $0. lastPathComponent < $1. lastPathComponent }
21+ func sortItems( foldersOnTop: Bool ) -> [ URL ] {
22+ return self . sorted { lhs, rhs in
23+ let lhsIsDir = ( try ? lhs. resourceValues ( forKeys: [ . isDirectoryKey] ) . isDirectory) ?? false
24+ let rhsIsDir = ( try ? rhs. resourceValues ( forKeys: [ . isDirectoryKey] ) . isDirectory) ?? false
2325
24- if foldersOnTop {
25- var foldersOnTop = alphabetically. filter { $0. isFolder }
26- alphabetically. removeAll { $0. isFolder }
26+ if foldersOnTop {
27+ if lhsIsDir != rhsIsDir {
28+ return lhsIsDir
29+ }
30+ }
2731
28- foldersOnTop. append ( contentsOf: alphabetically)
32+ return compareNaturally ( lhs. lastPathComponent, rhs. lastPathComponent)
33+ }
34+ }
2935
30- return foldersOnTop
31- } else {
32- return alphabetically
36+ /// Compare two strings using natural sorting.
37+ /// - Parameters:
38+ /// - lhs: The left-hand string.
39+ /// - rhs: The right-hand string.
40+ /// - Returns: `true` if `lhs` should be ordered before `rhs`.
41+ private func compareNaturally( _ lhs: String , _ rhs: String ) -> Bool {
42+ let lhsComponents = lhs. components ( separatedBy: CharacterSet . decimalDigits. inverted)
43+ let rhsComponents = rhs. components ( separatedBy: CharacterSet . decimalDigits. inverted)
44+
45+ for (lhsPart, rhsPart) in zip ( lhsComponents, rhsComponents) where lhsPart != rhsPart {
46+ if let lhsNum = Int ( lhsPart) , let rhsNum = Int ( rhsPart) {
47+ return lhsNum < rhsNum
48+ } else {
49+ return lhsPart < rhsPart
50+ }
3351 }
52+
53+ return lhs < rhs
3454 }
3555}
3656
0 commit comments