我有一个自定义对象的数组。该对象包含属性endDate。
我需要能够以类似于下面的sql:
的方式对我的数组进行排序order by enddate = 0 desc, enddate desc
我知道如何做第二部分:
arr.sorted(by : {$0.enddate > $1.enddate})
但我不知道如何通过有条件的enddate排序
输入
[{x: "blah", enddate : 123456}, {x: "blah2", enddate : 234567}, {x: "blah3", enddate : 345678}, {x: "blah4", enddate : 0}]
所以我希望输出让enddate降序,除非enddate是0,例如0, 345678, 234567, 123456
答案 0 :(得分:1)
在实现这些类型的自定义排序顺序时,您应该记住传递给sorted(by:)
的排序谓词的语义要求。这些要求列于in the documentation:
谓词必须是元素上的严格弱排序。那 是,对于任何元素a,b和c,必须满足以下条件:
areInIncreasingOrder(a, a)
始终为false
。 (Irreflexivity)- 如果
areInIncreasingOrder(a, b)
和areInIncreasingOrder(b, c)
都是true
,那么areInIncreasingOrder(a, c)
也是true
。 (传递 可比性)- 如果两个元素都不是根据谓词在另一个元素之前排序,则无法比较。如果a和b是无与伦比的,那么b和c 是无与伦比的,那么a和c也是无与伦比的。 (传递 不可比性)
不遵守这些要求可能会导致数组排序错误。因此,考虑到这些要求,这是表达排序顺序的一种方式:
struct S {
var endDate: Int
}
let arr = [S(endDate: 123456), S(endDate: 234567), S(endDate: 345678), S(endDate: 0)]
let result = arr.sorted {
switch ($0.endDate, $1.endDate) {
case (_, 0):
return false
case (0, _):
return true
case let (lhs, rhs):
return lhs > rhs
}
}
print(result)
// [S(endDate: 0), S(endDate: 345678), S(endDate: 234567), S(endDate: 123456)]
我们在这里使用的排序谓词是:
(0, 0)
是假的。其他(a, a)
其中a != 0
也是假的,因为>
也是不自反的。(0, a)
其中a != 0
为真,(a, 0)
为假。由>
处理的任何其他组合,具有可传递性的可比性。0
的给定对,另一个元素必须是0
才能无法比拟。因此,a == b == c == 0
和(a, c)
确实无法比拟。由>
处理的任何其他组合,它具有传递性,无法比拟。答案 1 :(得分:-1)
试试这个:
var sorted = data.sorted { $0.enddate == 0 ? true : $0.enddate > $1.enddate }