我想按字母順序對字串陣列進行排序,但有一個例外,某些元素應始終在陣列中排在第一位和第二位。以下是陣列的元素:
["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
})
它首先回傳斑馬,而不是貓第二
uj5u.com熱心網友回復:
當元素按升序排列時,傳遞給的閉包sorted(by:)應該回傳true,false否則回傳。除非同時檢查第一個值和第二個值,否則您無法判斷元素是否按升序排列。這就是為什么true當第一個值是“zebra”或“cat”時回傳不起作用的原因——并非所有的基礎都被覆寫。
一種解決方案是使用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"]
編輯:現在洗掉的評論質疑switch陳述句方法的可靠性。我用animals陣列的每個可能的順序對其進行了測驗,并且每次都回傳正確的結果。
uj5u.com熱心網友回復:
您可以使用列舉首先按 case 宣告順序比較的事實,然后按有效載荷值按字典順??序進行比較。此功能已在 Swift 5.3 中實作,請參閱
- SE-0266 列舉型別的綜合可比一致性
如果我們定義了一個列舉型別,其中“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"]
這種方法可以很容易地擴展到涵蓋更多的“特殊情況”。
uj5u.com熱心網友回復:
你要的答案是:
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;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/384071.html
