2016-08-07 7 views
5

Я пытаюсь разобрать следующий JSON:Swift: flatMap в словарь

{ 
    "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" 
    ] 
} 

Я также следуя tutorial. Это на Github в Playground

В примере, они разбор Array словарей с помощью typealias JSONDictionary = [String: AnyObject]

мне нужно разобрать Dictionary, который имеет Key, который String и Value, что является Array. Следовательно: typealias JSONDictionary = [String: [AnyObject]] и я получаю сообщение об ошибке при возврате 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) 
     } 
    } 
} 

Ошибка:

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

Как я могу получить словарь с Keys как String и Values как Array? Я хотел бы поддерживать их подход Generic.

ответ

5

Тип jsonString является Dictionary<String, Array<String>> Вы можете придать ему вид, как Dictionary<String, AnyObject>

AnyObject может содержать класс и структура т.е. Array, Dictionary, String, Int, классы Obj C , следовательно, Array<String> представлен AnyObjectне[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"] 

Как прокомментировал @dffri, вы можете использовать клавиши собственность на словаре, который будет возвращать LazyMapCollection, который будет реализовать, только если доступ к объекту внутри.

let keys = jsonString.keys 
+0

Спасибо. Это не печатает «ключи»? Как получить ключи как 'key' и' value' как 'Array'? – user1107173

+0

@ user1107173 Я обновил ответ, вы можете перейти к клавишам 'let keys = jsonString.flatMap {$ 0.0}' – Khundragpan

+1

Примечание: нет необходимости использовать 'flatMap' для ключей, так как там не было попытки лить (просто' let keys = jsonString.map {$ 0.0} 'достаточно). В качестве альтернативы используйте свойство 'keys' словаря, чтобы получить ключи как ленивую коллекцию:' let keys = jsonString.keys'. – dfri

Смежные вопросы