Swift - iterate array of dictionaries

21,905

You're having issues because Swift is unable to infer that books is an iterable type. If you know the type of the array going in, you should be explicitly casting to this type. If for example, the array should be an array of dictionaries which have strings as objects and keys, you should do the following.

if let books = jsonDict["book"] as? [[String:String]] {
    for bookDict in books {
        let title = bookDict["title"]
        println("title: \(title)")
    }
}

Also note that you have to remove the subscript dictionary access from the string interpolation because it contains quotation marks. You just have to do it on two lines.

Share:
21,905
soleil
Author by

soleil

Updated on July 22, 2020

Comments

  • soleil
    soleil almost 4 years

    Trying to find the title of each book:

    var error: NSError?
        let path = NSBundle.mainBundle().pathForResource("books", ofType: "json")
        let jsonData = NSData.dataWithContentsOfFile(path, options: .DataReadingMappedIfSafe, error: nil)
        let jsonDict = NSJSONSerialization.JSONObjectWithData(jsonData, options: nil, error: &error) as NSDictionary
        let books = jsonDict["book"]
    
        var bookTitles:[String]
    
        //for bookDict:Dictionary in books {
        //    println("title: \(bookDict["title"])")
        //}
    

    When I uncomment those last three lines, all hell breaks loose in Xcode6 beta3 - all text turns white, I get constant "SourceKitService Terminated" and "Editor functionality temporarily limited" popups, and I get these helpful build errors:

    <unknown>:0: error: unable to execute command: Segmentation fault: 11
    <unknown>:0: error: swift frontend command failed due to signal
    

    I have seriously offended the compiler here. So what is the correct way to iterate through the array of dictionaries and find the "title" property of each dict?

  • soleil
    soleil almost 10 years
    Thanks, this is helpful. What if the dictionary has some objects that are String:String and some that are String:Array? In this case for example, the book dictionary could contain a "chapter" key that has an array of chapter dictionaries.
  • Mick MacCallum
    Mick MacCallum almost 10 years
    @soleil In that case, you would probably want to use [[String:AnyObject]]. Of course this would mean that you would have to repeat the if let... to check which case you're currently dealing with.
  • rob5408
    rob5408 over 9 years
    If it helps anyone else, the [[String:String]] bit is saying "books is (potentially) an array of dictionaries where the key and value are both strings" or this format which is more familiar to me: Array<Dictionary<String,String>>