Szybka tablica z kluczy słownika


256

Próba szybkiego wypełnienia tablicy ciągami z kluczy w słowniku.

var componentArray: [String]

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

Zwraca błąd: „AnyObject” nie jest identyczny z łańcuchem

Próbowałem też

componentArray = dict.allKeys as String 

ale get: „String” nie jest konwertowany na [String]

Odpowiedzi:


534

Swift 3 i Swift 4

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

componentArray = dict.allKeys // for NSDictionary

Co ciekawe, w pętli for - dla nazwy w dict.allKeys - „nazwa” staje się łańcuchem i może być drukowana oraz przetwarzana w inny sposób.
green_knight

dict nie ma metody klucza. Jest to instancja NSDictionary, a nie Słownik.
Womble,

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

55

Dzięki Swift 3 Dictionaryma keyswłaściwość. keysma następującą deklarację:

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

Kolekcja zawierająca tylko klucze słownika.

Zauważ, że LazyMapCollectionto może być łatwo przyporządkowuje się do jednej Arrayz Array„s init(_:)inicjator.


Od NSDictionarydo[String]

Poniższy AppDelegatefragment kodu klasy iOS pokazuje, jak uzyskać tablicę ciągów ( [String]) za pomocą keyswłaściwości z NSDictionary:

wprowadź opis zdjęcia tutaj

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
}

Od [String: Int]do[String]

W bardziej ogólny sposób poniższy kod Playground pokazuje, jak uzyskać tablicę ciągów ( [String]) za pomocą keyswłaściwości ze słownika z kluczami ciągowymi i wartościami całkowitymi ( [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"]

Od [Int: String]do[String]

Poniższy kod Playground pokazuje, jak uzyskać tablicę ciągów ( [String]) za pomocą keyswłaściwości ze słownika z kluczami całkowitymi i wartościami ciągów ( [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"]

dzięki za szczegóły. W Swift 4.x typ jest Dictionary<String, String>.Keys- czy masz jakiś wgląd, kiedy chcielibyśmy użyć tego typu i jak?
bshirley,

46

Tablica z kluczy słownika w Swift

componentArray = [String] (dict.keys)

Nie wiem, dlaczego ludzie nie preferują skróconej składni, skoro jest o wiele bardziej zrozumiałe.
Natasha

9

dict.allKeysnie jest ciągiem. Jest to [String]dokładnie tak, jak mówi komunikat o błędzie (zakładając oczywiście, że klucze ciągami; to jest dokładnie to, co mówisz, kiedy to mówisz).

Więc zacznij od wpisania componentArrayjako [AnyObject], ponieważ jest to sposób wpisywania w interfejsie API Cocoa, lub, jeśli rzucisz dict.allKeys, rzuć to [String], ponieważ tak właśnie wpisałeś componentArray.


1
To nie wydaje się już prawdą. W Swift 4.2 dict.keys (który zastępuje .allKeys) nie jest [Ciągiem], jest [Słownikiem <Ciąg, Dowolnym> .Keys] i musi zostać rzutowany przed przypisaniem do zmiennej typu [Ciąg] @santo wydaje się mieć najprostszy działający przykład jak to zrobić.
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 is Class (pass by reference) Dictionary is Structure (pass by value ) ====== Tablica z NSDictionary ======NSDictionary jest typem klasy Słownik jest strukturą klucza i wartości

NSDictionary ma allKeys, a allValues uzyskuje właściwości typu [Any] .NSDictionary ma właściwości [Dowolne] dla wszystkich klawiszy i wszystkich wartości

  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)

====== Tablica ze słownika ======

Odwołanie Apple do właściwości kluczy i wartości Słownika . wprowadź opis zdjęcia tutaj

wprowadź opis zdjęcia tutaj

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

Z oficjalnej dokumentacji Apple Array :

init(_:) - Tworzy tablicę zawierającą elementy sekwencji.

Deklaracja

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

Parametry

s - Sekwencja elementów do przekształcenia w tablicę.

Dyskusja

Za pomocą tego inicjatora można utworzyć tablicę z dowolnego innego typu, który jest zgodny z protokołem sekwencji ... Można także użyć tego inicjatora do konwersji złożonej sekwencji lub typu kolekcji z powrotem na tablicę. Na przykład właściwość keys w słowniku nie jest tablicą z własnym miejscem do przechowywania, jest kolekcją, która odwzorowuje elementy ze słownika tylko wtedy, gdy są dostępne, oszczędzając czas i miejsce potrzebne do przydzielenia tablicy. Jeśli jednak musisz przekazać te klucze do metody, która pobiera tablicę, użyj tego inicjatora, aby przekonwertować tę listę z jej typu 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

Ta odpowiedź będzie dotyczyła szybkiego słownika z kluczami String. Jak ten poniżej .

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

Oto rozszerzenie, którego użyję.

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

I później zdobędę wszystkie klucze.

let componentsArray = dict.allKeys()

1

Szybki 5

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

let k = dict.keys

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

To działa dla mnie.


1

Możesz użyć Dictionary.map w następujący sposób:

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

Wyjaśnienie: Mapa iteruje przez myDictionary i akceptuje każdą parę kluczy i wartości jako 0 USD. Stąd możesz uzyskać 0,0 USD lub 0,0 USD. W końcowym zamknięciu {} możesz przekształcić każdy element i zwrócić ten element. Ponieważ chcesz 0 $ i chcesz go jako ciąg, następnie dokonujesz konwersji za pomocą String (klucz 0,0 $). Zbierasz przekształcone elementy do tablicy ciągów.


-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
No hej! Ten fragment kodu może być rozwiązaniem, ale wyjaśnienie naprawdę pomaga poprawić jakość posta. Pamiętaj, że w przyszłości odpowiadasz na pytanie dla czytelników, a ci ludzie mogą nie znać przyczyn Twojej sugestii kodu.
Skrzydło
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.