2015-05-29 148 views
1

這是我按position屬性對元素進行排序時的方法。 DBSetDBItem都有該屬性。如何在Swift中使用兩種對象對數組進行排序?

@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 
    } 
} 

positionInt16

型我如何簡化?

+0

你能同時顯示你的兩個對象類型的聲明? (DBSet和DBItem) –

+0

他們來自核心數據... –

回答

2

創建一個定義您的位置屬性的協議。我們稱之爲HasPosition。聲明一個[HasPosition]的數組。然後您可以使用任何標準分類功能直接對數組進行排序。

+0

這種類型擦除有很大的缺點... –

+1

雖然,我猜這些類型已經徹底抹去了他目前在這裏的任何東西...... –

+0

不是元素必須是類型[AnyObject]才能包含多種類型?解釋我的解決方案如何丟失信息? (不是狡猾的......你對Swift的瞭解比我多) –

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被定義爲小於任何非零值。因此,這兩種類型之一的數組而不是中的值將排序到開頭。

1

當你有數組作爲[AnyObject]positionInt16,這應該工作:

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

這工作,因爲AnyObject有任何@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()可以簡化爲:

private func prepareElements() { 
    elements = [] 
    if let ct = currentCategory { 
     elements += Array(ct.items) as [AnyObject] 
     elements += Array(ct.sets) as [AnyObject] 
     elements.sort { 
      ($0.position as Int16?) < ($1.position as Int16?) 
     } 
    } 
} 
相關問題