Matriz de teclas de dicionário em rápida

256

Tentando preencher uma matriz com seqüências de caracteres das teclas em um dicionário rapidamente.

var componentArray: [String]

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

Isso retorna um erro de: 'AnyObject' não idêntico à string

Também tentei

componentArray = dict.allKeys as String 

mas get: 'String' não é conversível em [String]

Kyle Goslan
fonte

Respostas:

534

Swift 3 e Swift 4

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

componentArray = dict.allKeys // for NSDictionary
Andrius Steponavičius
fonte
Curiosamente, em um loop for - para nome em dict.allKeys - 'name' torna-se uma string e pode ser impressa e processada.
green_knight
dict não possui um método de chaves. É uma instância do NSDictionary, não um Dicionário.
Womble
2
dict.map {$ 0.key}
Nilanshu Jaiswal 20/11/19
55

Com Swift 3, Dictionarytem uma keyspropriedade. keystem a seguinte declaração:

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

Uma coleção que contém apenas as chaves do dicionário.

Note que LazyMapCollectionque pode facilmente ser mapeado para um Arraycom Array's init(_:)initializer.


De NSDictionaryaté[String]

O seguinte AppDelegatesnippet de classe do iOS mostra como obter uma matriz de strings ( [String]) usando a keyspropriedade de NSDictionary:

insira a descrição da imagem aqui

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]até[String]

De uma maneira mais geral, o seguinte código do Playground mostra como obter uma matriz de strings ( [String]) usando a keyspropriedade de um dicionário com chaves de string e valores inteiros ( [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]até[String]

O seguinte código do Playground mostra como obter uma matriz de strings ( [String]) usando a keyspropriedade de um dicionário com chaves inteiras e valores de string ( [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"]
Imanou Petit
fonte
obrigado pelo detalhe. No Swift 4.x, o tipo é Dictionary<String, String>.Keys: você tem alguma ideia de quando queremos usar esse tipo e como?
bshirley
46

Matriz de teclas de dicionário no Swift

componentArray = [String] (dict.keys)
Santo
fonte
Não sei por que as pessoas não preferem a sintaxe abreviada enquanto é muito mais claro para entender.
Natasha
9

dict.allKeysnão é uma string. É [String]exatamente como a mensagem de erro informa (assumindo, é claro, que as chaves são todas cadeias; é exatamente isso que você está afirmando quando diz isso).

Portanto, comece digitando componentArraycomo [AnyObject], porque é assim que é digitado na API do cacau ou, se você o lança dict.allKeys, lança para [String], porque é assim que você digitou componentArray.

mate
fonte
1
Isso não parece mais verdade. No Swift 4.2, dict.keys (que substitui .allKeys) não é uma [String], é uma [Dictionary <String, Any> .Keys] e deve ser convertida antes de atribuir a uma variável do tipo [String] @santo parece ter o exemplo mais simples de como fazer isso.
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
    }
}
Jitesh Desai
fonte
3

NSDictionary é Class (passa por referência) Dictionary is Structure (passa por valor ) NSDictionary é o tipo de classe Dicionário é estrutura de chave e valor ====== Matriz de NSDictionary ======

O NSDictionary possui allKeys e allValues obtém propriedades com o tipo [Any] .O NSDictionary possui propriedades get [Any] para allkeys e 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 do dicionário ======

Referência da Apple para as propriedades de valores e chaves do Dicionário . insira a descrição da imagem aqui

insira a descrição da imagem aqui

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)
Darshan Panchal
fonte
3

A partir da documentação oficial da Apple Array :

init(_:) - Cria uma matriz contendo os elementos de uma sequência.

Declaração

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

Parâmetros

s - A sequência de elementos para se transformar em uma matriz.

Discussão

Você pode usar esse inicializador para criar uma matriz a partir de qualquer outro tipo que esteja em conformidade com o protocolo de sequência ... Você também pode usar esse inicializador para converter uma sequência complexa ou um tipo de coleção em uma matriz. Por exemplo, a propriedade keys de um dicionário não é uma matriz com seu próprio armazenamento, é uma coleção que mapeia seus elementos do dicionário somente quando são acessados, economizando tempo e espaço necessários para alocar uma matriz. Se você precisar passar essas chaves para um método que utiliza uma matriz, use esse inicializador para converter essa lista do seu 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"]"
Chris Graf
fonte
1

Esta resposta será para o dicionário rápido com teclas String. Como este abaixo .

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

Aqui está a extensão que vou 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 }
  }
}

E eu vou pegar todas as chaves depois usando isso.

let componentsArray = dict.allKeys()
jnblanchard
fonte
1

Swift 5

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

let k = dict.keys

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

Isso funciona para mim.

Siddharth Kavthekar
fonte
1

Você pode usar o dictionary.map assim:

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

A explicação: Map itera através do myDictionary e aceita cada par de chave e valor como $ 0. A partir daqui, você pode obter $ 0.key ou $ 0.value. Dentro do fechamento à direita {}, você pode transformar cada elemento e retornar esse elemento. Como você deseja $ 0 e deseja como uma string, converte usando String ($ 0.key). Você coleta os elementos transformados em uma matriz de cadeias.

Meo Flute
fonte
-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 }
    }
}
Igor Bachek
fonte
2
Olá! Embora esse snippet de código possa ser a solução, incluir uma explicação realmente ajuda a melhorar a qualidade da sua postagem. Lembre-se de que você está respondendo à pergunta dos leitores no futuro e essas pessoas podem não saber os motivos da sua sugestão de código.
Wing