webentwicklung-frage-antwort-db.com.de

tippen hat keine tiefgestellten Mitglieder

Ich möchte Adressen aus dem Profilwörterbuch erhalten, aber ich habe den Fehler "Geben Sie" keine? "?

var address:[[String : Any]] = [["Address": "someLocation", "City": "ABC","Zip" : 123],["Address": "someLocation", "City": "DEF","Zip" : 456]]
var profile:[String : Any] = ["Name": "Mir", "Age": 10, "Addresses": address]
profile["Addresses"][0]     <-----------------type any? has no subscript members

Wie kann ich das Problem beheben und die Adresse erhalten? Danke vielmals.

11
KKG

Wenn Sie ein Profil mit "Addresses" abonnieren, erhalten Sie eine Any-Instanz zurück. Ihre Wahl für die Verwendung von Any für verschiedene Typen innerhalb desselben Arrays hat zum Löschen des Typs geführt. Sie müssen das Ergebnis wieder in seinen echten Typ [[String: Any]] umwandeln, damit es weiß, dass die Any-Instanz eine Array darstellt. Dann können Sie es abonnieren:

func f() {
    let address: [[String : Any]] = [["Address": "someLocation", "City": "ABC","Zip" : 123],["Address": "someLocation", "City": "DEF","Zip" : 456]]
    let profile: [String : Any] = ["Name": "Mir", "Age": 10, "Addresses": address]

    guard let addresses = profile["Addresses"] as? [[String: Any]] else {
        // Either profile["Addresses"] is nil, or it's not a [[String: Any]]
        // Handle error here
        return
    }

    print(addresses[0])
}

Dies ist jedoch sehr unübersichtlich und es ist kein sehr geeigneter Fall, Wörterbücher überhaupt zu verwenden.

In einer solchen Situation, in der Sie Wörterbücher mit einem festen Satz von Schlüsseln haben, sind die Strukturen eher geeignet. Sie sind stark typisiert, Sie müssen also nicht von Any hoch und runter gehen, sie haben eine bessere Leistung und sind viel einfacher zu handhaben. Versuche dies:

struct Address {
    let address: String
    let city: String
    let Zip: Int
}

struct Profile {
    let name: String
    let age: Int
    let addresses: [Address]
}

let addresses = [
    Address(
        address: "someLocation"
        city: "ABC"
        Zip: 123
    ),
    Address(
        address: "someLocation"
        city: "DEF"
        Zip: 456
    ),
]

let profile = Profile(name: "Mir", age: 10, addresses: addresses)

print(profile.addresses[0]) //much cleaner/easier!
18
Alexander

Sie sollten sich überlegen, wie Sie adress und profile konstruiert haben. siehe z. Alexander Momchliovs Antwort .


Für die technische Diskussion können Sie could die Any Mitglieder von profile extrahieren, von denen Sie wissen, dass sie [String: Any] Wörterbücher enthalten, die in Any array; durch sequentielle versuchte Typkonvertierung von profile["Addresses"] in [Any] gefolgt von elementweiser (versuchte) Konvertierung in [String: Any]:

if let adressDictsWrapped = profile["Addresses"] as? [Any] {
    let adressDicts = adressDictsWrapped.flatMap{ $0 as? [String: Any] }
    print(adressDicts[0]) // ["Zip": 123, "City": "ABC", "Address": "someLocation"]
    print(adressDicts[1]) // ["Zip": 456, "City": "DEF", "Address": "someLocation"]
}

oder ohne Zwischenschritt ...

if let adressDicts = profile["Addresses"] as? [[String: Any]] {
   print(adressDicts[0]) // ["Zip": 123, "City": "ABC", "Address": "someLocation"]
   print(adressDicts[1]) // ["Zip": 456, "City": "DEF", "Address": "someLocation"]
}

Dies ist jedoch nur eine kleine Lektion in der versuchten getippten Konvertierung (-> mach das nicht).

2
dfri

Ich stimme dem zu, wenn Sie Ihr Design wie zuvor vorgeschlagen überdenken. Im Interesse der Diskussion können Sie Folgendes ausführen, um das zu erreichen, was Sie suchen.

var address:[[String : Any]] = [["Address": "someLocation", "City": "ABC","Zip" : 123],["Address": "someLocation", "City": "DEF","Zip" : 456]]
var profile:[String : Any] = ["Name": "Mir", "Age": 10, "Addresses": address]
if let allAddresses = profile["Addresses"] as? [[String:Any]] {
    print("This are all the address \(allAddresses[0])")
    }
0
Reginaldo Costa