使用Swift按对象的枚举值对数组进行排序。

3

我有一个CLBeacon对象数组,这些对象都有一个属性.proximity。

我希望按照包含CLProximity枚举的这个属性对数组进行排序。所以,我希望所有对象按照IMMEDIATE、NEAR、FAR、UNKNOWN的顺序排列。

有没有一种简洁的方法可以做到这一点,而不必通过一堆if语句来实现?


我曾考虑按照rawValue排序,但在这种情况下,这并不起作用,因为Unknown是枚举中的第一个(而我希望它排在最后)。 - Alper
我现在能想到的最简单的方法是创建一个集合来分配它们的整数值,以便您可以进行比较。 - Julia Will
有什么快速完成这个任务的代码吗?可以给它们打上编号并压缩成zip文件吗? - Alper
5个回答

16

如果您定义了CLProximity的一个(计算只读)属性sortIndex

extension CLProximity {
    var sortIndex : Int {
        switch self {
        case .Immediate:
            return 0
        case .Near:
            return 1
        case .Far:
            return 2
        case .Unknown:
            return 3
        }
    }
}

然后,您可以使用以下方法对信标数组进行排序:

let sortedBeacons = sorted(beacons) { $0.proximity.sortIndex < $1.proximity.sortIndex }

如果.Unknown是唯一需要“特殊处理”的CLProximity值,而所有其他可能的值都按期望的相对顺序排列,则可以简化属性定义为

如果只有.Unknown需要“特殊处理”,而其他所有可能的值都处于期望的相对顺序中,则可以将属性定义简化为:

extension CLProximity {
    var sortIndex : Int {
        return self == .Unknown ? Int.max : rawValue
    }
}

这很好,如果能将正确的数据附加到CLProximity上会更好,尽管我不确定如何实现。 - Alper

1
你可以使用自定义比较器来对数组进行排序,
你需要为所有具有“未知”接近度的对象“声明”它们比其他对象“更大”。
var sortedArray = persons.sortedArrayUsingComparator {
    (obj1, obj2) -> NSComparisonResult in


    if obj1.proximity.rawValue == obj12.proximity.rawValue {
        return NSComparisonResult.OrderedSame
    } else if obj1.proximity == .UNKNOWN || obj1.proximity.rawValue > obj12.proximity.rawValue {
        return NSComparisonResult.OrderedDescending
    }
    return NSComparisonResult.OrderedAscending
}

0

Swift 5

现在你可以只需将Comparable添加到你的枚举类型中,它就会尊重顺序。

enum ContainerLevel: Comparable {
case empty
case almostEmpty
case halfFull
case almostFull
case full    

}

//Are we running low?

let needMoreCoffee = coffeeMugLevel > .halfFull

print(needMoreCoffee) //true

更多代码示例链接


0
基于@Martin的回答。 您还可以创建Int枚举并为其分配值,然后像下面一样进行排序。
enum myEnum: Int {
    case A = 0
    case B = 1
    case C = 2
    case D = 3
}
let myData : [myEnum:[String]] = [.C:["3"],.D:["4"],.B:["2"],.A:["1"]]
print(myData.first?.key)

let newData = myData.sorted(by: { $0.key.rawValue < $1.key.rawValue })
print(newData.first?.key)

希望这能有所帮助。

0

根据Julia上面写的,我把这个东西拼凑起来了:

    self.beacons = beacons as! [CLBeacon]

    var tempBeacons = zip(self.beacons, self.beacons.map({
        (b: CLBeacon) -> Int in
        if b.proximity == .Immediate {
            return 0
        } else if b.proximity == .Near {
            return 1
        } else if b.proximity == .Far {
            return 2
        } else if b.proximity == .Unknown {
            return 3
        }
        return 0
    }))

    self.beacons = sorted(tempBeacons, {$0.1 < $1.1}).map({ $0.0 })

谢谢大家!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接