如何在Swift中使用两种对象对数组进行排序?

时间:2015-05-29 11:12:54

标签: swift sorting

当我按position属性对元素进行排序时,这是我的方法。 DBSetDBItem都有该属性。

@objc(DBCategory)
class DBCategory: NSManagedObject {

    @NSManaged var identifier: String
    @NSManaged var items: Set<DBItem>
    @NSManaged var sets: Set<DBSet>

}

这就是我使用它的方式

private var elements = [AnyObject]()

private func prepareElements() {
    elements.removeAll(keepCapacity: false)
    if let items = currentCategory?.items {
        for item in items {
            elements.append(item)
        }
    }

    if let sets = currentCategory?.sets {
        for set in sets {
            elements.append(set)
        }
    }

    elements.sort {
        var previousPosition = 0
        var currentPosition = 0
        if let set = $0 as? DBSet {
            previousPosition = Int(set.position)
        }

        if let item = $0 as? DBItem {
            previousPosition = Int(item.position)
        }

        if let set = $1 as? DBSet {
            currentPosition = Int(set.position)
        }

        if let item = $1 as? DBItem {
            currentPosition = Int(item.position)
        }

        return previousPosition < currentPosition
    }
}

position的类型为Int16

我该如何简化?

3 个答案:

答案 0 :(得分:2)

创建一个定义您的位置属性的协议。我们称之为HasPosition。声明[HasPosition]的数组。然后,您可以使用任何标准排序函数直接对数组进行排序。

答案 1 :(得分:1)

如果.position在两种情况下返回相同的类型,该类型具有可比性,则可以将其简化为以下内容:

elements.sort {
    let l = ($0 as? DBSet)?.position ?? ($0 as? DBItem)?.position
    let r = ($1 as? DBSet)?.position ?? ($1 as? DBItem)?.position
    return l < r
}

这项工作的关键是有<版本适用于期权,其中nil定义为小于任何非零值。因此,两种类型之一的数组中的值将被排序到开头。

答案 2 :(得分:1)

当您将数组设为[AnyObject]positionInt16时,这应该有效:

elements.sort {
    ($0.position as Int16?) < ($1.position as Int16?)
}

这是有效的,因为AnyObject的{​​{1}}属性为@objc

演示:

Optional

您的class DBItem:NSObject { var position:Int16 init(position: Int16) { self.position = position } override var description:String { return "DBItem(\(position))" } } class DBSet:NSObject { var position:Int16 init(position: Int16) { self.position = position } override var description:String { return "DBSet(\(position))" } } var elements:[AnyObject] = [ DBItem(position: 5), DBSet(position: 2), DBItem(position: 42), DBSet(position: 62), DBSet(position: 21), DBItem(position: 6), DBSet(position: 36), DBItem(position: 24), ] elements.sort { ($0.position as Int16?) < ($1.position as Int16?) } println(elements) // -> [DBSet(2), DBItem(5), DBItem(6), DBSet(21), DBItem(24), DBSet(36), DBItem(42), DBSet(62)] 可以简化为:

prepareElements()