对带有异常的字符串数组进行排序 Swift
Posted
技术标签:
【中文标题】对带有异常的字符串数组进行排序 Swift【英文标题】:Sort string array with exceptions Swift 【发布时间】:2022-01-20 00:54:57 【问题描述】:我想按字母顺序对字符串数组进行排序,但有一个例外是某些元素应始终在数组中排在第一位和第二位。以下是数组的元素:
["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
)
它首先返回斑马,但不是猫第二
【问题讨论】:
我建议将你不想开始的那些移到一个单独的数组中。然后故事数组。 @SathyaBaman 应该有一种使用排序方法的方法 【参考方案1】:当元素按升序排列时,传递给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"]
编辑: 一条现已删除的评论质疑switch
语句方法的可靠性。我用animals
数组的所有可能顺序对其进行了测试,每次都返回正确的结果。
【讨论】:
【参考方案2】:您可以使用枚举首先按 case 声明顺序进行比较,然后按字典顺序按有效负载值进行比较的事实。此功能在 Swift 5.3 中实现,请参阅
SE-0266 Synthesized Comparable conformance for enum types如果我们定义一个枚举类型,“斑马”和“猫”的情况在前
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"]
这种方法可以很容易地扩展到涵盖更多“特殊情况”。
【讨论】:
【参考方案3】:你想要的答案是:
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的主要内容,如果未能解决你的问题,请参考以下文章
求C语言编程编写函数sort:对数组a中的数进行从小到大排序
对字符串中字符进行自然顺序排序(基本类型排序)-冒泡算法实现