Swift: flatMap to Dictionary

I am trying to parse the following JSON:

{ "String For Key 1": [ "Some String A", "Some String B", "Some String C", ], "String For Key 2": [ "Some String D", "Some String E", "Some String F" ], "String For Key 3": [ "Some String G", "Some String H", "Some String I", ], "String For Key 4": [ "Some String J", "Some String K", "Some String L" ], "String For Key 5": [ "Some String M", "Some String N", "Some String O" ], "String For Key 6": [ "Some String P", "Some String Q", "Some String R" ] } 

I also follow this tutorial . This is on Github in the playground.

In this example, they parse the words Array dictionaries using typealias JSONDictionary = [String: AnyObject]

I need to parse a Dictionary that has Key , which is String , and Value , which is Array . Hence: typealias JSONDictionary = [String: [AnyObject]] and I get an error when returning flatMap .

 extension Resource { init(url: NSURL, parseJSON: AnyObject -> A?) { self.url = url self.parse = { data in let json = try? NSJSONSerialization.JSONObjectWithData(data, options: []) as? [String: [AnyObject]] //This is where I get an error return json.flatMap(parseJSON) } } } 

Error:

 Cannot convert value of type `AnyObject -> A? to expected argument type `([String: [AnyObject]]?) -> _? 

How can I get a dictionary with Keys as String and Values as Array ? I would like to support their Generic approach.

+5
source share
1 answer

JsonString type Dictionary<String, Array<String>> You can give it a type of type Dictionary<String, AnyObject>

AnyObject may contain a class and structure ie Array , Dictionary , String , Int , Obj classes C Therefore, Array<String> is represented by AnyObject not [AnyObject]

 let jsonString:[String: AnyObject] = [ "String For Key 1": [ "http://www.urlToSomePathA.jpg", "http://www.urlToSomePathB.jpg", "http://www.urlToSomePathC.jpg", ], "String For Key 2": [ "http://www.urlToSomePathD.jpg", "http://www.urlToSomePathE.jpg", "http://www.urlToSomePathF.jpg" ] ] // Now you can map a function on the value type let values = jsonString.flatMap { $0.1 as? [String] } print(values) // RESULT: [["http://www.urlToSomePathA.jpg", "http://www.urlToSomePathB.jpg", "http://www.urlToSomePathC.jpg"], ["http://www.urlToSomePathD.jpg", "http://www.urlToSomePathE.jpg", "http://www.urlToSomePathF.jpg"]] 

Update

 let keys = jsonString.flatMap { $0.0 } // ["String For Key 1", "String For Key 2"] 

As @dffri commented, you can use the keys property in a dictionary that returns a LazyMapCollection , which will only be implemented when accessing the object inside.

 let keys = jsonString.keys 
+5
source

All Articles