Matrice dalle chiavi del dizionario in rapido


256

Prova di riempire rapidamente un array con stringhe delle chiavi di un dizionario.

var componentArray: [String]

let dict = NSDictionary(contentsOfFile: NSBundle.mainBundle().pathForResource("Components", ofType: "plist")!)
componentArray = dict.allKeys

Ciò restituisce un errore di: 'AnyObject' non identico alla stringa

Anche provato

componentArray = dict.allKeys as String 

ma get: 'String' non è convertibile in [String]

Risposte:


534

Swift 3 e Swift 4

componentArray = Array(dict.keys) // for Dictionary

componentArray = dict.allKeys // for NSDictionary

È interessante notare che in un ciclo for - per nome in dict.allKeys - 'nome' diventa una stringa e può essere stampato e altrimenti elaborato.
green_knight

dict non ha un metodo keys. È un'istanza di NSDictionary, non un dizionario.
Womble,

2
dict.map {$ 0.key}
Nilanshu Jaiswal

55

Con Swift 3, Dictionaryha una keysproprietà. keysha la seguente dichiarazione:

var keys: LazyMapCollection<Dictionary<Key, Value>, Key> { get }

Una raccolta contenente solo le chiavi del dizionario.

Si noti che LazyMapCollectionche può facilmente essere mappati a un Arraycon Array's init(_:)inizializzatore.


Da NSDictionarya[String]

Il seguente AppDelegateframmento di classe iOS mostra come ottenere una matrice di stringhe ( [String]) usando la keysproprietà di un NSDictionary:

inserisci qui la descrizione dell'immagine

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    let string = Bundle.main.path(forResource: "Components", ofType: "plist")!
    if let dict = NSDictionary(contentsOfFile: string) as? [String : Int] {
        let lazyMapCollection = dict.keys
        
        let componentArray = Array(lazyMapCollection)
        print(componentArray)
        // prints: ["Car", "Boat"]
    }
    
    return true
}

Da [String: Int]a[String]

In un modo più generale, il seguente codice Playground mostra come ottenere una matrice di stringhe ( [String]) usando la keysproprietà di un dizionario con chiavi stringa e valori interi ( [String: Int]):

let dictionary = ["Gabrielle": 49, "Bree": 32, "Susan": 12, "Lynette": 7]
let lazyMapCollection = dictionary.keys

let stringArray = Array(lazyMapCollection)
print(stringArray)
// prints: ["Bree", "Susan", "Lynette", "Gabrielle"]

Da [Int: String]a[String]

Il seguente codice Playground mostra come ottenere una matrice di stringhe ( [String]) usando la keysproprietà di un dizionario con chiavi intere e valori stringa ( [Int: String]):

let dictionary = [49: "Gabrielle", 32: "Bree", 12: "Susan", 7: "Lynette"]
let lazyMapCollection = dictionary.keys
    
let stringArray = Array(lazyMapCollection.map { String($0) })
// let stringArray = Array(lazyMapCollection).map { String($0) } // also works
print(stringArray)
// prints: ["32", "12", "7", "49"]

grazie per il dettaglio. In Swift 4.x il tipo è Dictionary<String, String>.Keys: hai qualche idea quando vorremmo usare quel tipo e come?
bshirley,

46

Matrice dalle chiavi del dizionario in Swift

componentArray = [String] (dict.keys)

Non so perché le persone non preferiscono la sintassi abbreviata mentre è molto più chiaro da capire.
Natasha,

9

dict.allKeysnon è una stringa. È [String]esattamente come ti dice il messaggio di errore (supponendo, ovviamente, che le chiavi siano tutte stringhe; questo è esattamente ciò che stai affermando quando lo dici).

Quindi, o inizia digitando componentArrayas [AnyObject], perché è così che è stato digitato nell'API Cocoa, oppure, se lo fai dict.allKeys, esegui il cast [String], perché è così che hai digitato componentArray.


1
Questo non sembra più vero. In Swift 4.2 dict.keys (che sostituisce .allKeys) non è un [String], è un [Dizionario <String, Any> .Keys] e deve essere lanciato prima di assegnare a una variabile di tipo [String] @santo sembra avere l'esempio di lavoro più semplice su come farlo.
timeSmith

5
extension Array {
    public func toDictionary<Key: Hashable>(with selectKey: (Element) -> Key) -> [Key:Element] {
        var dict = [Key:Element]()
        for element in self {
            dict[selectKey(element)] = element
        }
        return dict
    }
}

3

NSDictionary è Class (passa per riferimento) Dictionary is Structure (passa per valore ) ====== Matrice da NSDictionary ======NSDictionary è di tipo classe Il dizionario è una struttura di chiave e valore

NSDictionary ha allKeys e allValues ottengono proprietà con tipo [Any] .NSDictionary ha proprietà [Any] per tutte le chiavi e tutti i valori

  let objesctNSDictionary = 
    NSDictionary.init(dictionary: ["BR": "Brazil", "GH": "Ghana", "JP": "Japan"])
            let objectArrayOfAllKeys:Array = objesctNSDictionary.allKeys
            let objectArrayOfAllValues:Array = objesctNSDictionary.allValues
            print(objectArrayOfAllKeys)
            print(objectArrayOfAllValues)

====== Matrice dal dizionario ======

Riferimento Apple per le proprietà di chiavi e valori del dizionario . inserisci qui la descrizione dell'immagine

inserisci qui la descrizione dell'immagine

let objectDictionary:Dictionary = 
            ["BR": "Brazil", "GH": "Ghana", "JP": "Japan"]
    let objectArrayOfAllKeys:Array = Array(objectDictionary.keys)          
    let objectArrayOfAllValues:Array = Array(objectDictionary.values)
    print(objectArrayOfAllKeys)
    print(objectArrayOfAllValues)


3

Dalla documentazione ufficiale di Apple sull'array :

init(_:) - Crea un array contenente gli elementi di una sequenza.

Dichiarazione

Array.init<S>(_ s: S) where Element == S.Element, S : Sequence

parametri

s - La sequenza di elementi da trasformare in un array.

Discussione

È possibile utilizzare questo inizializzatore per creare un array da qualsiasi altro tipo conforme al protocollo Sequence ... È inoltre possibile utilizzare questo inizializzatore per convertire una sequenza complessa o un tipo di raccolta in un array. Ad esempio, la proprietà keys di un dizionario non è un array con una propria memoria, è una raccolta che mappa i suoi elementi dal dizionario solo quando vi si accede, risparmiando il tempo e lo spazio necessari per allocare un array. Se è necessario passare quelle chiavi a un metodo che accetta un array, utilizzare questo inizializzatore per convertire tale elenco dal suo tipo di LazyMapCollection<Dictionary<String, Int>, Int> to a simple [String].

func cacheImagesWithNames(names: [String]) {
    // custom image loading and caching
 }

let namedHues: [String: Int] = ["Vermillion": 18, "Magenta": 302,
        "Gold": 50, "Cerise": 320]
let colorNames = Array(namedHues.keys)
cacheImagesWithNames(colorNames)

print(colorNames)
// Prints "["Gold", "Cerise", "Magenta", "Vermillion"]"

2

Puoi usare dizionario.map in questo modo:

let myKeys: [String] = myDictionary.map{String($0.key) }

La spiegazione: la mappa scorre attraverso myDictionary e accetta ogni coppia chiave e valore come $ 0. Da qui puoi ottenere $ 0.key o $ 0.value. All'interno della chiusura finale {}, puoi trasformare ogni elemento e restituirlo. Dal momento che vuoi $ 0 e lo vuoi come stringa, allora converti usando String (tasto $ 0.). Raccogli gli elementi trasformati in una matrice di stringhe.


1

Questa risposta sarà per il dizionario rapido con i tasti String. Come questo qui sotto .

let dict: [String: Int] = ["hey": 1, "yo": 2, "sup": 3, "hello": 4, "whassup": 5]

Ecco l'estensione che userò.

extension Dictionary {
  func allKeys() -> [String] {
    guard self.keys.first is String else {
      debugPrint("This function will not return other hashable types. (Only strings)")
      return []
    }
    return self.flatMap { (anEntry) -> String? in
                          guard let temp = anEntry.key as? String else { return nil }
                          return temp }
  }
}

E riceverò tutte le chiavi in ​​seguito usando questo.

let componentsArray = dict.allKeys()

1

Swift 5

var dict = ["key1":"Value1", "key2":"Value2"]

let k = dict.keys

var a: [String]()
a.append(contentsOf: k)

Questo funziona per me.


-2
// Old version (for history)
let keys = dictionary.keys.map { $0 }
let keys = dictionary?.keys.map { $0 } ?? [T]()

// New more explained version for our ducks
extension Dictionary {

    var allKeys: [Dictionary.Key] {
        return self.keys.map { $0 }
    }
}

2
Ehilà! Sebbene questo frammento di codice possa essere la soluzione, includere una spiegazione aiuta davvero a migliorare la qualità del tuo post. Ricorda che stai rispondendo alla domanda per i lettori in futuro e quelle persone potrebbero non conoscere i motivi del tuo suggerimento sul codice.
Ala
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.