Matriz de teclas de diccionario en swift


256

Intentando llenar una matriz con cadenas de las teclas en un diccionario en forma rápida.

var componentArray: [String]

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

Esto devuelve un error de: 'AnyObject' no idéntico a la cadena

También probé

componentArray = dict.allKeys as String 

pero obtener: 'String' no es convertible a [String]

Respuestas:


534

Swift 3 y Swift 4

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

componentArray = dict.allKeys // for NSDictionary

Curiosamente, en un bucle for - for name en dict.allKeys - 'name' se convierte en una cadena y puede imprimirse y procesarse de otra manera.
green_knight

dict no tiene un método de claves. Es una instancia de NSDictionary, no un diccionario.
Womble

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

55

Con Swift 3, Dictionarytiene una keyspropiedad. keystiene la siguiente declaración:

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

Una colección que contiene solo las claves del diccionario.

Tenga en cuenta que LazyMapCollectiontan fácilmente se puede asignar a una Arraycon Array's init(_:)inicializador.


De NSDictionarya[String]

El siguiente AppDelegatefragmento de clase de iOS muestra cómo obtener una matriz de cadenas ( [String]) usando la keyspropiedad de a NSDictionary:

ingrese la descripción de la imagen aquí

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
}

De [String: Int]a[String]

De manera más general, el siguiente código de Playground muestra cómo obtener una matriz de cadenas ( [String]) usando la keyspropiedad de un diccionario con claves de cadena y valores enteros ( [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"]

De [Int: String]a[String]

El siguiente código de Playground muestra cómo obtener una matriz de cadenas ( [String]) usando la keyspropiedad de un diccionario con claves enteras y valores de cadena ( [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"]

Gracias por el detalle. En Swift 4.x, el tipo es Dictionary<String, String>.Keys: ¿tiene alguna idea de cuándo queremos usar ese tipo y cómo?
bshirley

46

Matriz de teclas de diccionario en Swift

componentArray = [String] (dict.keys)

No sé por qué las personas no prefieren la sintaxis abreviada mientras es mucho más claro de entender.
Natasha

9

dict.allKeysNo es una cadena. Es [String]exactamente lo que le dice el mensaje de error (suponiendo, por supuesto, que las claves son todas cadenas; esto es exactamente lo que está afirmando cuando dice eso).

Por lo tanto, comience escribiendo componentArraycomo [AnyObject], porque así es como se escribe en la API de Cocoa, o bien, si lanza dict.allKeys, envíe a [String], porque así es como ha escrito componentArray.


1
Esto ya no parece cierto. En Swift 4.2 dict.keys (que reemplaza a .allKeys) no es una [String], es un [Dictionary <String, Any> .Keys] y debe emitirse antes de asignar a una variable de tipo [String] @santo parece tener El ejemplo de trabajo más simple de cómo hacerlo.
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 es Clase (pase por referencia) Diccionario es Estructura (pase por valor ) ====== Matriz de NSDictionary ======NSDictionary es tipo de clase El diccionario es una estructura de clave y valor

NSDictionary tiene allKeys y allValues obtiene propiedades con el tipo [Any] .NSDictionary tiene propiedades [Any] para allkeys y 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)

====== Matriz del diccionario ======

Referencia de Apple para las propiedades de valores y claves del Diccionario . ingrese la descripción de la imagen aquí

ingrese la descripción de la imagen aquí

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

De la documentación oficial de Array Apple :

init(_:) - Crea una matriz que contiene los elementos de una secuencia.

Declaración

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

Parámetros

s - La secuencia de elementos para convertir en una matriz.

Discusión

Puede usar este inicializador para crear una matriz a partir de cualquier otro tipo que se ajuste al protocolo de secuencia ... También puede usar este inicializador para convertir una secuencia compleja o un tipo de colección a una matriz. Por ejemplo, la propiedad de claves de un diccionario no es una matriz con su propio almacenamiento, es una colección que asigna sus elementos del diccionario solo cuando se accede a ellos, ahorrando el tiempo y el espacio necesarios para asignar una matriz. Sin embargo, si necesita pasar esas claves a un método que toma una matriz, use este inicializador para convertir esa lista de su tipo de 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

Puede usar dictionary.map así:

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

La explicación: Map itera a través de myDictionary y acepta cada par de clave y valor como $ 0. Desde aquí puede obtener $ 0.key o $ 0.value. Dentro del cierre final {}, puede transformar cada elemento y devolver ese elemento. Como quieres $ 0 y lo quieres como una cadena, entonces conviertes usando String ($ 0.key). Recopila los elementos transformados en una serie de cadenas.


1

Esta respuesta será para un diccionario rápido con teclas de cadena. Como este a continuación .

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

Aquí está la extensión que usaré.

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

Y obtendré todas las claves más tarde usando esto.

let componentsArray = dict.allKeys()

1

Swift 5

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

let k = dict.keys

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

Esto funciona para mi.


-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
¡Hola! Si bien este fragmento de código puede ser la solución, incluir una explicación realmente ayuda a mejorar la calidad de su publicación. Recuerde que está respondiendo la pregunta para los lectores en el futuro, y que esas personas podrían no saber los motivos de su sugerencia de código.
Ala
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.