2014-11-12 20 views
11

Sto usando CoreData quindi ho bisogno di sorta descrittori per i miei soggettiSwift: Ordina Array per descrittori di ordinamento

Per esempio, una coordinata-entità ha questa classe func:

class func sortDescriptors() -> Array<NSSortDescriptor> 
{ 
    return [NSSortDescriptor(key: "sequence", ascending: true)] 
} 

Sto usando questo quando facendo fetch-domande di CoreData simili:

var request = NSFetchRequest(entityName: entityName) 

request.sortDescriptors = T.sortDescriptors() 

Tuttavia, in presenza di un array di coordinate come una proprietà su un altro oggetto CoreData, questo è un NSSet (Ie indifferenziati)

per risolvere questo, torno le coordinate del genere:

return NSArray(array: coordinates!).sortedArrayUsingDescriptors(Coordinate.sortDescriptors()) as? Array<Coordinate> 

che si sente brutta, per usare un NSArray solo per ottenere il sortedArrayUsingDescriptors -Metodo. C'è un modo simile per farlo direttamente su un array Swift, I.e. Array<Coordinate> usando descrittori di ordinamento?

Grazie!

+0

Perché non usare 'sortedArrayUsingDescriptors di NSSet'() metodo' '? – rintaro

+0

Potrei farlo anche io! Ma la domanda è ancora valida; è siscriptors di ordinamento compatibili con gli array Swift? – ullstrm

+0

Le istanze di @rintaro 'NSSet' non sono ordinate per definizione. Suppongo che tu ti stia riferendo a 'NSArray'. –

risposta

10

non esiste alcun metodo incorporato per questo, ma è possibile aggiungere utilizzando protocollo di estensione:

extension MutableCollectionType where Index : RandomAccessIndexType, Generator.Element : AnyObject { 
    /// Sort `self` in-place using criteria stored in a NSSortDescriptors array 
    public mutating func sortInPlace(sortDescriptors theSortDescs: [NSSortDescriptor]) { 
     sortInPlace { 
      for sortDesc in theSortDescs { 
       switch sortDesc.compareObject($0, toObject: $1) { 
       case .OrderedAscending: return true 
       case .OrderedDescending: return false 
       case .OrderedSame: continue 
       } 
      } 
      return false 
     } 
    } 
} 

extension SequenceType where Generator.Element : AnyObject { 
    /// Return an `Array` containing the sorted elements of `source` 
    /// using criteria stored in a NSSortDescriptors array. 
    @warn_unused_result 
    public func sort(sortDescriptors theSortDescs: [NSSortDescriptor]) -> [Self.Generator.Element] { 
     return sort { 
      for sortDesc in theSortDescs { 
       switch sortDesc.compareObject($0, toObject: $1) { 
       case .OrderedAscending: return true 
       case .OrderedDescending: return false 
       case .OrderedSame: continue 
       } 
      } 
      return false 
     } 
    } 
} 

Ma nota che questo sistema funziona solo quando gli elementi dell'array sono classi, non strutture, come NSSortDescriptor compareObject il metodo richiede argomenti conformi a AnyObject

+0

Grandi complimenti a te! Questo è stato un problema per me. Grazie per avermi aiutato. – Tobonaut

8

Un altro approccio alle estensioni di Damien potrebbe essere un multi-cast.

myArray = (myArray as NSArray).sortedArrayUsingDescriptors(tableView.sortDescriptors) as! Array 

Fonte originale: NSHipster

4

Swift 3 Versione di @ risposta di Darniel

extension MutableCollection where Self : RandomAccessCollection { 
    /// Sort `self` in-place using criteria stored in a NSSortDescriptors array 
    public mutating func sort(sortDescriptors theSortDescs: [NSSortDescriptor]) { 
     sort { by: 
      for sortDesc in theSortDescs { 
       switch sortDesc.compare($0, to: $1) { 
       case .orderedAscending: return true 
       case .orderedDescending: return false 
       case .orderedSame: continue 
       } 
      } 
      return false 
     } 

    } 
} 

extension Sequence where Iterator.Element : AnyObject { 
    /// Return an `Array` containing the sorted elements of `source` 
    /// using criteria stored in a NSSortDescriptors array. 

    public func sorted(sortDescriptors theSortDescs: [NSSortDescriptor]) -> [Self.Iterator.Element] { 
     return sorted { 
      for sortDesc in theSortDescs { 
       switch sortDesc.compare($0, to: $1) { 
       case .orderedAscending: return true 
       case .orderedDescending: return false 
       case .orderedSame: continue 
       } 
      } 
      return false 
     } 
    } 
} 
Problemi correlati