Array von Wörterbuchschlüsseln in schnell


256

Der Versuch, ein Array schnell mit Zeichenfolgen aus den Schlüsseln eines Wörterbuchs zu füllen.

var componentArray: [String]

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

Dies gibt den Fehler "AnyObject" zurück, der nicht mit der Zeichenfolge identisch ist

Auch versucht

componentArray = dict.allKeys as String 

aber get: 'String' kann nicht in [String] konvertiert werden

Antworten:


534

Swift 3 & Swift 4

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

componentArray = dict.allKeys // for NSDictionary

Interessanterweise wird in einer for-Schleife - for name in dict.allKeys - 'name' zu einer Zeichenfolge und kann gedruckt und auf andere Weise verarbeitet werden.
green_knight

dict hat keine Schlüsselmethode. Es ist eine Instanz von NSDictionary, kein Dictionary.
Womble

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

55

Mit Swift 3 Dictionaryhat eine keysEigenschaft. keyshat die folgende Erklärung:

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

Eine Sammlung, die nur die Schlüssel des Wörterbuchs enthält.

Beachten Sie, dass LazyMapCollectiondie leicht zu einem abgebildet werden kann Arraymit Array‚s init(_:)initializer.


Von NSDictionarybis[String]

Das folgende iOS- AppDelegateKlassen-Snippet zeigt, wie Sie ein Array von Strings ( [String]) mithilfe der keysEigenschaft von a abrufen NSDictionary:

Geben Sie hier die Bildbeschreibung ein

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
}

Von [String: Int]bis[String]

Allgemeiner zeigt der folgende Playground-Code, wie ein Array von Zeichenfolgen ( [String]) mithilfe der keysEigenschaft aus einem Wörterbuch mit Zeichenfolgenschlüsseln und Ganzzahlwerten ( [String: Int]) abgerufen wird :

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"]

Von [Int: String]bis[String]

Der folgende Spielplatzcode zeigt, wie Sie ein Array von Zeichenfolgen ( [String]) mithilfe der keysEigenschaft aus einem Wörterbuch mit Ganzzahlschlüsseln und Zeichenfolgenwerten ( [Int: String]) abrufen :

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"]

danke für das detail. In Swift 4.x lautet der Typ Dictionary<String, String>.Keys: Haben Sie einen Einblick, wann und wie wir diesen Typ verwenden möchten?
Bshirley

46

Array aus Wörterbuchschlüsseln in Swift

componentArray = [String] (dict.keys)

Ich weiß nicht, warum die Leute die Kurzschrift-Syntax nicht bevorzugen, obwohl es viel klarer zu verstehen ist.
Natasha

9

dict.allKeysist kein String. Es ist ein [String], genau wie die Fehlermeldung Ihnen sagt , (vorausgesetzt natürlich, dass die Schlüssel sind alle Strings, das ist genau das, was Sie behaupten , wenn Sie das sagen).

Beginnen Sie also entweder mit der Eingabe componentArrayals [AnyObject], da dies in der Cocoa-API so eingegeben wird, oder, wenn Sie dict.allKeyses übertragen, in [String], weil Sie es so eingegeben haben componentArray.


1
Dies scheint nicht mehr wahr zu sein. In Swift 4.2 ist dict.keys (das .allKeys ersetzt) ​​kein [String], sondern ein [Dictionary <String, Any> .Keys] und muss umgewandelt werden, bevor eine Variable vom Typ [String] @santo zugewiesen wird das einfachste Arbeitsbeispiel dafür.
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 ist Klasse (Referenzübergabe) Wörterbuch ist Struktur (Wertübergabe ) ====== Array von NSDictionary ======NSDictionary ist ein Klassentyp Wörterbuch ist die Struktur von Schlüssel und Wert

NSDictionary verfügt über allKeys und allValues erhalten Eigenschaften vom Typ [Any] .NSDictionary verfügt über [Any] -Eigenschaften für allkeys und allvalues

  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)

====== Array aus dem Wörterbuch ======

Apple - Referenz für Dictionary Schlüssel und Werte Eigenschaften. Geben Sie hier die Bildbeschreibung ein

Geben Sie hier die Bildbeschreibung ein

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

Aus der offiziellen Array Apple-Dokumentation :

init(_:) - Erstellt ein Array mit den Elementen einer Sequenz.

Erklärung

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

Parameter

s - Die Folge von Elementen, die in ein Array umgewandelt werden sollen.

Diskussion

Mit diesem Initialisierer können Sie ein Array aus einem anderen Typ erstellen, der dem Sequenzprotokoll entspricht. Mit diesem Initialisierer können Sie auch einen komplexen Sequenz- oder Sammlungstyp zurück in ein Array konvertieren. Beispielsweise ist die keys-Eigenschaft eines Wörterbuchs kein Array mit eigenem Speicher, sondern eine Sammlung, die ihre Elemente nur dann auf das Wörterbuch abbildet, wenn auf sie zugegriffen wird, wodurch Zeit und Platz gespart werden, die zum Zuweisen eines Arrays erforderlich sind. Wenn Sie diese Schlüssel jedoch an eine Methode übergeben müssen, die ein Array verwendet, verwenden Sie diesen Initialisierer, um diese Liste von ihrem Typ zu konvertieren 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"]"

1

Diese Antwort gilt für ein schnelles Wörterbuch mit String-Schlüsseln. Wie dieser unten .

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

Hier ist die Erweiterung, die ich verwenden werde.

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

Und ich werde später alle Schlüssel damit bekommen.

let componentsArray = dict.allKeys()

1

Swift 5

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

let k = dict.keys

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

Das funktioniert bei mir.


1

Sie können dictionary.map wie folgt verwenden:

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

Die Erklärung: Map durchläuft das myDictionary und akzeptiert jedes Schlüssel- und Wertepaar als $ 0. Von hier aus können Sie $ 0.key oder $ 0.value erhalten. Innerhalb des nachfolgenden Verschlusses {} können Sie jedes Element transformieren und dieses Element zurückgeben. Da Sie $ 0 und es als String wollen, konvertieren Sie mit String ($ 0.key). Sie sammeln die transformierten Elemente in einem Array von Zeichenfolgen.


-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
Sie da! Während dieses Code-Snippet die Lösung sein kann, hilft das Hinzufügen einer Erklärung wirklich, die Qualität Ihres Beitrags zu verbessern. Denken Sie daran, dass Sie die Frage für Leser in Zukunft beantworten und diese Personen möglicherweise die Gründe für Ihren Codevorschlag nicht kennen.
Flügel
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.