這個問題在這里已經有了答案: 用數字按字母順序排序陣列 8 個答案 2天前關閉。
我將嘗試用文字來定義問題,但是使用示例測驗用例更容易解釋這一點。
"b" > "a"
"3" > "1"
"ac" > "ab"
"32" > "25"
"abcd1" > "abc2"
"abc123a" > "abc2a"
"abc123a" < "abc1234a"
"abc123" < "abc123a"
"abc12a49" > "abc12a39"
"123ab3" = "123ab3"
"ab12" > "12ab"
"ab12" > "345"
我需要比較字母數字字串。當字串中只有數字或只有字符時,這是微不足道的,但是當它們組合在一起時,它變得更加復雜。基本上,如果我有意義的話,我需要將數字組作為一個整數而不是單個數字進行比較。
以下是我嘗試過的。將字串拆分為字母和數字組是一種蠻力方法。我認為這行得通,但它不是很好,也不是很優雅。有沒有更好的方法來實作這一點。我幾乎拋棄了在操場上運行所需的所有依賴擴展和方法,非常抱歉缺少格式。
extension RangeReplaceableCollection {
mutating func removeFirstSafe() -> Element? {
guard !isEmpty else { return nil }
return removeFirst()
}
}
extension String {
func split(grouping charSets: [[Character]]) -> [(CharacterType, String)] {
var subStrings = [(CharacterType, String)]()
var copy = self
copy.__split(grouping: charSets, groupedSubstrings: &subStrings)
return subStrings
}
mutating func __split(grouping charSets: [[Character]], groupedSubstrings: inout [(CharacterType, String)]) {
guard let previousCharacter: Character = removeFirstSafe() else {
return
}
var groupedSubString = String(previousCharacter)
let prevCharSetGroup: CharacterType = charSets.indexOfCharSetGroupContainingCharacter(previousCharacter)
while let currentCharacter = first, charSets.indexOfCharSetGroupContainingCharacter(currentCharacter) == prevCharSetGroup {
groupedSubString.append(currentCharacter)
removeFirst()
}
groupedSubstrings.append((prevCharSetGroup, groupedSubString))
__split(grouping: charSets, groupedSubstrings: &groupedSubstrings)
}
}
enum CharacterType: Int, Comparable {
case alphabet = 1
case number = 0
case unknown = -1
static func < (lhs: CharacterType, rhs: CharacterType) -> Bool {
lhs.rawValue < rhs.rawValue
}
}
extension Array where Element == [Character] {
func indexOfCharSetGroupContainingCharacter(_ char: Character) -> CharacterType {
for (index, group) in self.enumerated() {
if group.contains(char) { return CharacterType(rawValue: index) ?? .unknown }
}
return .unknown
}
}
extension Collection {
subscript (safe index: Index) -> Element? {
return indices.contains(index) ? self[index] : nil
}
}
struct AlphanumericString {
var string: String
}
func <(lhs: (CharacterType, String), rhs: (CharacterType, String)) -> Bool {
if lhs.0 > rhs.0 { return false }
else if lhs.0 < rhs.0 { return true }
else {
if lhs.0 == .alphabet || lhs.0 == .unknown { return lhs.1 < rhs.1 }
else { return (Int(lhs.1) ?? 0) < (Int(rhs.1) ?? 0) }
}
}
extension AlphanumericString: Comparable {
static func < (lhs: AlphanumericString, rhs: AlphanumericString) -> Bool {
if lhs.string == rhs.string { return false }
let lhsGrouped = lhs.string.split(grouping: [Array("12345"), Array("abcde")])
let rhsGrouped = rhs.string.split(grouping: [Array("12345"), Array("abcde")])
for idx in lhsGrouped.indices {
let lhsItem = lhsGrouped[idx]
guard let rhsItem = rhsGrouped[safe: idx] else { return false }
if lhsItem < rhsItem { return true }
else if rhsItem < lhsItem { return false }
}
return true
}
}
print(AlphanumericString(string: "abcd1") < AlphanumericString(string: "abc2"))
uj5u.com熱心網友回復:
這是微不足道的
確實如此,因為有一個 API:localizedStandardCompare(_:)
描述是比較由 Finder 排序的字串。
func numericCompare(lhs: String, rhs: String, mode: ComparisonResult) -> Bool {
lhs.localizedStandardCompare(rhs) == mode
}
numericCompare(lhs: "b" ,rhs: "a", mode: .orderedDescending) // true
numericCompare(lhs: "3" ,rhs: "1", mode: .orderedDescending) // true
numericCompare(lhs: "ac" ,rhs: "ab", mode: .orderedDescending) // true
numericCompare(lhs: "32" ,rhs: "25", mode: .orderedDescending) // true
numericCompare(lhs: "abcd1" ,rhs: "abc2", mode: .orderedDescending) // true
numericCompare(lhs: "abc123a" ,rhs: "abc2a", mode: .orderedDescending) // true
numericCompare(lhs: "abc123a" ,rhs: "abc1234a", mode: .orderedAscending) // true
numericCompare(lhs: "abc123" ,rhs: "abc123a", mode: .orderedAscending) // true
numericCompare(lhs: "abc12a49" ,rhs: "abc12a39", mode: .orderedDescending) // true
numericCompare(lhs: "123ab3" ,rhs: "123ab3", mode: .orderedSame) // true
另一種方法是lhs.compare(rhs, options: .numeric)做同樣的事情
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/488641.html
上一篇:第二次被叫后我的間隔沒有繼續
