2015-04-09 25 views
5

Quando si crea un dizionario chiave/valore, viene restituito come ordinato in ordine casuale. Speravo che sarebbero stati nello stesso ordine in cui è stato creato.Conserva l'ordine degli elementi del dizionario come dichiarato in Swift?

Ad esempio, si veda questo codice:

var dict = [ 
    "kg": 1, 
    "g": 2, 
    "mg": 3, 
    "lb": 4, 
    "oz": 5, 
    "t": 6 
] 

println(dict) 

Ciò restituisce il seguente:

[kg: 1, oz: 5, g: 2, mg: 3, lb: 4, t: 6] 

Come faccio a mantenere l'ordine in cui il dizionario è stato dichiarato?

+3

Il [documentazione] (https://developer.apple.com/library/ios/documentation/General/Reference/SwiftStandardLibraryReference/Dictionary.html) afferma chiaramente: Un Dizionario è un tipo generico che gestisce un * * raccolta non ordinata ** di coppie chiave-valore.- Vedi anche http://stackoverflow.com/questions/26546488/dictionary-printing-results-backwards. –

+0

Devi creare il tuo tipo che contiene il dizionario e l'ordine. Non esiste un tipo incorporato per farlo. – Kirsteins

+0

Bummer, questa è una grande limitazione. Non voglio ordinare per chiavi o valori, voglio solo che compaiano nell'ordine in cui sono stati dichiarati. – TruMan1

risposta

9

Nel tuo caso un serie di costume gli oggetti potrebbero essere più appropriati. Ecco un semplice esempio che dovrebbe aiutare a iniziare:

struct Unit : Printable { 
    let name: String 
    let factor: Double 

    // println() should print just the unit name: 
    var description: String { return name } 
} 


let units = [ 
    Unit(name: "kg", factor: 1000.0), 
    Unit(name: "g", factor: 1.0), 
    Unit(name: "mg", factor: 0.001), 
    Unit(name: "lb", factor: 453.592292), 
    Unit(name: "oz", factor: 28.349523) 
] 

println(units) // [kg, g, mg, lb, oz] 

(non sono sicuro se i fattori di unità non metriche sono corretti :)

+0

Ah molto intelligente, grazie! – TruMan1

-1
struct MenueItem { 
let title : String 
let image : String} 


let items = [MenueItem(title: "Readers", image: "multimedia"), 
      MenueItem(title: "Live Broadcast", image: "multimedia"), 
      MenueItem(title: "Quran Browsing", image: "multimedia"), 
      MenueItem(title: "Personal Quran", image: "multimedia"), 
      MenueItem(title: "Videos", image: "multimedia"), 
      MenueItem(title: "Favorites", image: "favorites")] 

....

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    return items.count 

....

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCellWithIdentifier("MenuTableViewCell", forIndexPath: indexPath) as! MenuTableViewCell 

    cell.cellTitle.text = items[indexPath.row].title 
    cell.cellImage.image = UIImage(named: items[indexPath.row].image) 
    return cell 
} 
} 
+0

come mai ?? !! Ho risposto alla domanda a modo mio ... Sto dando un esempio rispondendo alla domanda .. l'esempio è la risposta !! Stava chiedendo l'ordine dei dizionari in modo rapido e sto affrontando lo stesso problema e l'ho risolto creando una serie di strutture ?? !! – Abo3atef

2

Purtroppo, Apple ha integrato solo tre strutture di raccolta in Swift. Queste sono la matrice, il dizionario e il set. Fortunatamente, Apple ha introdotto una gerarchia di protocolli molto ampia e potente che supporta la definizione di classi di raccolta personalizzate in modo semplice ed elegante.

Quindi, se non ti interessa lo spazio addizionale (e forse anche il tempo) della tua soluzione, potresti decidere di costruire la tua classe/struttura di raccolta Swift che assomiglia a un dizionario che conserva l'ordine in cui elementi sono stati aggiunti ad esso, correlando gli indici alle chiavi e viceversa. Vedere la documentazione per ulteriori informazioni sulla creazione di proprie raccolte dati di raccolte: https://developer.apple.com/documentation/swift/collection.

io ti do un po 'di qualcosa per farti andare:

responsabilità: Questo codice è non testato, e non ho speso una grande quantità di pensiero in materia di complessità algoritmica. Si prega di determinare i requisiti della soluzione e verificare personalmente se il seguente codice è conforme.

public struct KeepOrderDictionary<Key, Value> where Key : Hashable 
{ 
    public private(set) var values: [Value] 

    fileprivate var keyToIndexMap: [Key:Int] 
    fileprivate var indexToKeyMap: [Int:Key] 

    public init() 
    { 
     self.values = [Value]() 
     self.keyToIndexMap = [Key:Int]() 
     self.indexToKeyMap = [Int:Key]() 
    } 

    public var count: Int 
    { return values.count} 

    public mutating func add(key: Key, _ value: Value) 
    { 
     if let index = keyToIndexMap[key] 
     { values[index] = value} 
     else 
     { 
      values.append(value) 
      keyToIndexMap[key] = values.count - 1 
      indexToKeyMap[values.count - 1] = key 
     } 
    } 

    public mutating func add(index: Int, _ value: Value) -> Bool 
    { 
     if let key = indexToKeyMap[index] 
     { 
      add(key: key, value) 
      return true 
     } 

     return false 
    } 

    public func get(key: Key) -> (Key, Value)? 
    { 
     if let index = keyToIndexMap[key] 
     { return (key, values[index])} 

     return nil 
    } 

    public func get(index: Int) -> (Key, Value)? 
    { 
     if let key = indexToKeyMap[index] 
     { return (key, values[index])} 

     return nil 
    } 

    public mutating func removeValue(forKey key: Key) -> Bool 
    { 
     guard let index = keyToIndexMap[key] else 
     { return false} 

     values.remove(at: index) 

     keyToIndexMap.removeValue(forKey: key) 
     indexToKeyMap.removeValue(forKey: index) 

     return true 
    } 

    public mutating func removeValue(at index: Int) -> Bool 
    { 
     guard let key = indexToKeyMap[index] else 
     { return false} 

     values.remove(at: index) 

     keyToIndexMap.removeValue(forKey: key) 
     indexToKeyMap.removeValue(forKey: index) 

     return true 
    } 
} 

extension KeepOrderDictionary 
{ 
    public subscript(key: Key) -> Value? 
     { 
     get 
     { return get(key: key)?.1} 

     set 
     { 
      if let newValue = newValue 
      { add(key: key, newValue)} 
      else 
      { let _ = removeValue(forKey: key)} 
     } 
    } 

    public subscript(index: Int) -> Value? 
     { 
     get 
     { return get(index: index)?.1} 

     set 
     { 
      if let newValue = newValue 
      { let _ = add(index: index, newValue)} 
     } 
    } 
} 

extension KeepOrderDictionary : ExpressibleByDictionaryLiteral 
{ 
    public init(dictionaryLiteral elements: (Key, Value)...) 
    { 
     self.init() 
     for entry in elements 
     { add(key: entry.0, entry.1)} 
    } 
} 

extension KeepOrderDictionary : Sequence 
{ 
    public typealias Iterator = IndexingIterator<[(key: Key, value: Value)]> 

    public func makeIterator() -> KeepOrderDictionary.Iterator 
    { 
     var content = [(key: Key, value: Value)]() 

     for i in 0 ..< count 
     { 
      if let value: Value = self[i], let key: Key = indexToKeyMap[i] 
      {  content.append((key: key, value: value))} 
     } 

     return content.makeIterator() 
    } 
} 
Problemi correlati