将nil排序到可选字符串数组的末尾

时间:2018-11-22 01:02:46

标签: arrays swift sorting optional

如果我有一个可选字符串数组,并且想要以nils开头的升序对其进行排序,那么我可以轻松地在一行中完成它:

["b", nil, "a"].sorted{ $0 ?? "" < $1 ?? "" } // [nil, "a", "b"]

但是似乎没有类似的简单解决方案可以将nil排序到数组的 end 。可以使用其他大多数简单数据类型轻松完成此操作,例如:

[2, nil, 1].sorted{ $0 ?? Int.max < $1 ?? Int.max } // [1, 2, nil]

对于双打,您可以对greatestFiniteMagnitude进行同样的操作;对于日期,可以使用distantFuture。字符串是否有任何等效形式,或者有其他简洁的方式可以避免编写一堆凌乱的条件语句?

3 个答案:

答案 0 :(得分:2)

您可以提供一个考虑nil的自定义比较器 大于任何非null值:

let array = ["b", nil, "a", nil]

let sortedArray = array.sorted { (lhs, rhs) -> Bool in
    switch (lhs, rhs) {
    case let(l?, r?): return l < r // Both lhs and rhs are not nil
    case (nil, _): return false    // Lhs is nil
    case (_?, nil): return true    // Lhs is not nil, rhs is nil
    }
}

print(sortedArray) // [Optional("a"), Optional("b"), nil, nil]

这适用于任何可选的可比较元素数组,并避免了 “神奇大”值的用法。比较器可以实现 作为通用函数:

func compareOptionalsWithLargeNil<T: Comparable>(lhs: T?, rhs: T?) -> Bool {
    switch (lhs, rhs) {
    case let(l?, r?): return l < r // Both lhs and rhs are not nil
    case (nil, _): return false    // Lhs is nil
    case (_?, nil): return true    // Lhs is not nil, rhs is nil
    }
}

print(["b", nil, "a", nil].sorted(by: compareOptionalsWithLargeNil))
// [Optional("a"), Optional("b"), nil, nil]

print([2, nil, 1].sorted(by: compareOptionalsWithLargeNil))
// [Optional(1), Optional(2), nil]

print([3.0, nil, 1.0].sorted(by: compareOptionalsWithLargeNil))
// [Optional(1.0), Optional(3.0), nil]

print([Date(), nil, .distantPast, nil, .distantFuture].sorted(by: compareOptionalsWithLargeNil))
// [Optional(0000-12-30 00:00:00 +0000), Optional(2018-11-22 13:56:03 +0000),
//  Optional(4001-01-01 00:00:00 +0000), nil, nil]

答案 1 :(得分:1)

一个nil与另一个没有区别。因此,如果您有一个可行的解决方案可以按照您的期望进行排序,只是在开始时会弹出nil项,请使用它,然后删除nil项并附加相同数量的{{1} }到末尾。

示例:

nil

答案 2 :(得分:1)

您使用Int的示例提供了一个线索。如果我们有一个最大字符串值,我们可以将其插入。

这适用于仅包含字母字符的字符串:

let maxString = "~"
["b", nil, "a"].sorted{ $0 ?? maxString < $1 ?? maxString }

或者简单地:

["b", nil, "a"].sorted{ $0 ?? "~" < $1 ?? "~" }