Created
May 4, 2020 13:20
-
-
Save TimOliver/8c70605c16b855623fc68ea3ca433b0e to your computer and use it in GitHub Desktop.
An algorithm I wrote to sort a list of file paths in varying levels of directories into ascending order
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extension String { | |
/// Compares the current string value as a file path against a second | |
/// file path string in order to determine which comes first. | |
/// | |
/// Rules: | |
/// * Item names are only compared if they are in the same directory | |
/// * Items in higher parent directories always take priority | |
/// * Files prefixed with "_" are automatically downgraded (Since files prefixed like that are usually ads) | |
/// | |
/// - Parameter secondString: The string to compare this string against | |
/// - Returns: `true` if the ordering is ascending, and `false` otherwise | |
public func filePathCompare(with secondString: String) -> Bool { | |
// Format the inputs to remove any possible leading slashes | |
var firstFilePath = self.deletingPrefix("/") | |
var secondFilePath = secondString.deletingPrefix("/") | |
// If one URL has less slashes (ie, the item is in a parent directory), favour that one | |
let firstFolderCount = firstFilePath.countInstances(of: "/") | |
let secondFolderCount = secondFilePath.countInstances(of: "/") | |
if firstFolderCount != secondFolderCount { | |
return firstFolderCount < secondFolderCount | |
} | |
// Loop through until we go past the front of either URL | |
while firstFilePath.lastPathComponent != ".." && secondFilePath.lastPathComponent != ".." { | |
// Get the last component of the file path | |
let firstFileName = firstFilePath.lastPathComponent | |
let secondFileName = secondFilePath.lastPathComponent | |
// Remove the components from the file paths | |
firstFilePath = firstFilePath.deletingLastPathComponent | |
secondFilePath = secondFilePath.deletingLastPathComponent | |
// If the truncated file paths don't match, go up one more level until they do | |
if firstFilePath.compare(secondFilePath) != .orderedSame { | |
continue | |
} | |
// Once the truncated file URLs match, this means the items being compared | |
// are both in the same directory. We can do a file name compare to determine | |
// the ordering | |
// Always give lower priority to files pre-fixed with '_' | |
if firstFileName.hasPrefix("_") { return false } | |
if secondFileName.hasPrefix("_") { return true } | |
// Perform a compare on just the file names | |
return firstFileName.localizedCompare(secondFileName) == .orderedAscending | |
} | |
// Default to ascending (But this should never be called) | |
return true | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment