Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
740 views
in Technique[技术] by (71.8m points)

arrays - type any? has no subscript members

I want to get Addresses from profile dictionary,but I got the error "type any? has no subscript members"

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

How can I fix it and get the address? Thanks a lot.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

When you subscript profile with "Addresses", you're getting an Any instance back. Your choice to use Any to fit various types within the same array has caused type erasure to occur. You'll need to cast the result back to its real type, [[String: Any]] so that it knows that the Any instance represents an Array. Then you'll be able to subscript it:

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

This is very clunky though, and it's not a very appropriate case to be using Dictionaries in the first place.

In such a situation, where you have dictionaries with a fixed set of keys, structs are a more more appropriate choice. They're strongly typed, so you don't have to do casting up and down from Any, they have better performance, and they're much easier to work with. Try this:

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!

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...