[英]Sort string array with exceptions Swift
我想按字母順序對字符串數組進行排序,但除了某些元素應始終在數組中排序第一和第二。 以下是數組的元素:
["cat", "dog", "bird", "zebra", "elephant"]
我希望它按字母順序排序,但zebra
總是第一, cat
總是第二,所以排序后它應該看起來像:
["zebra", "cat", "bird", "dog", "elephant"]
這就是我的處理方式:
let animals = ["cat", "dog", "bird", "zebra", "elephant"]
animals = animals.sorted(by: { first, second in
if first == "zebra" {return true}
if first == "cat" {return true}
return first < second
})
它首先返回斑馬,但不是貓第二
當元素按升序排列時,傳遞給sorted(by:)
的閉包應該返回true
,否則返回false
。 除非您同時檢查第一個值和第二個值,否則您無法判斷元素是否按升序排列。 這就是為什么當第一個值為“zebra”或“cat”時返回true
是行不通的——並不是所有的基礎都被覆蓋了。
一種解決方案是使用switch
語句根據您正在查看的值指定比較邏輯:
let animals = ["cat", "dog", "bird", "zebra", "elephant"].sorted {
switch ($0, $1) {
case ("zebra", "cat"): // zebra is before cat
return true
case ("cat", "zebra"): // cat is not before zebra
return false
case ("cat", _), ("zebra", _): // zebra/cat are before everything
return true
case (_, "cat"), (_, "zebra"): // zebra/cat are not after anything
return false
case let (lhs, rhs): // alphabetical order
return lhs < rhs
}
}
// ["zebra", "cat", "bird", "dog", "elephant"]
如果這看起來有點過度設計,那是因為它是。 像這樣覆蓋你的所有基礎是很困難的,所以我絕對建議你看看你的用例,並考慮你是否真的需要這樣做。 如果你能擺脫一些更簡單的事情,那可能是你最好的選擇。 例如:
let animals = ["zebra", "cat"] + ["dog", "bird", "elephant"].sorted()
// ["zebra", "cat", "bird", "dog", "elephant"]
或者,如果animals
數組無法修改,另一種選擇是硬編碼異常:
let exceptions = ["zebra", "cat"]
let otherAnimals = animals.filter { !exceptions.contains($0) }.sorted()
let sortedResult = exceptions + otherAnimals
// ["zebra", "cat", "bird", "dog", "elephant"]
你要的答案是:
var animals = ["cat", "dog", "bird", "zebra", "elephant"]
animals = animals.sorted(by: { first, second in
if first == "cat" && second == "zebra" {return false;}
if second == "cat" && first == "zebra" {return true;}
if first == "zebra" || first == "cat" {return true;}
if second == "zebra" || second == "cat" {return false;}
return first < second
})
您甚至可以在排序之前嘗試調用animals.shuffle()
以檢查排序是否有效,而不管輸入順序如何。
這是一種更易讀的方法,盡管效率可能較低:
var animals = ["cat", "dog", "bird", "zebra", "elephant"]
animals = animals.sorted();
var wordIndex:Int = animals.firstIndex(where: {$0 == "zebra"})!;
animals.insert(animals.remove(at: wordIndex), at: 0);
wordIndex = animals.firstIndex(where: {$0 == "cat"})!;
animals.insert(animals.remove(at: wordIndex), at: 1);
或者,如果您想要更通用的版本:
func sortAndPrepend(inputArr: [String], prependWords: [String]) -> [String]{
var array = inputArr.sorted();
var wordIndex:Int;
for i in 0...prependWords.count-1 {
wordIndex = array.firstIndex(where: {$0 == prependWords[i]}) ?? -1;
if (wordIndex != -1) {
array.insert(array.remove(at: wordIndex), at: i);
}
}
return array;
}
您可以使用枚舉首先按案例聲明順序進行比較的事實,然后按字典順序按有效負載值進行比較。 此功能在 Swift 5.3 中實現,請參閱
如果我們用“zebra”和“cat”案例定義一個枚舉類型,首先排序
enum AnimalOrder: Comparable {
case zebra
case cat
case other(String)
init(animal: String) {
switch animal {
case "zebra": self = .zebra
case "cat": self = .cat
default: self = .other(animal)
}
}
}
然后只需使用即可實現所需的排序
let animals = ["cat", "dog", "bird", "zebra", "elephant"]
let sorted = animals.sorted(by: {
AnimalOrder(animal: $0) < AnimalOrder(animal: $1)
})
print(sorted) // ["zebra", "cat", "bird", "dog", "elephant"]
這種方法可以很容易地擴展到涵蓋更多“特殊情況”。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.