2017-05-16 1 views
0

Meine Klasse zu initialisieren, kann aus einer JSON DictionaryMit map() Array Inline von Array von Dictionary (dh ein JSON-Array)

class ChildObject { 
    required init?(fromDictionary dictionary: [String:Any]) { //init... } 
} 

Und jetzt war ich ein Array solcher Wörterbücher gegeben initialisiert werden:

// objectDictionaries = [[String:Any]] 

Jetzt möchte ich ein Array meiner Klasse inline mit map initialisieren. Ich initialisiere ein Array innerhalb einer anderen Klasse.

class ParentObject { 
     var children: [ChildObject] 

     required init?(fromDictionary aDictionary: [String:Any]) { 
      guard let childDictionaries = aDictionary["children"] as? [[String:Any]], 
       let children = childDictionaries.map { ChildObject(fromDictionary: $0) } 
       else { return nil } 
      self.children = children 
     } 

} 

Aber das kompiliert nicht --- kann mir jemand die richtige Syntax sagen? Ich habe versucht forEach, aber das hat auch nicht funktioniert.

In einem Spielplatz erhalte ich

  • nach guard Erwartet sonst
  • Anonymous Schließung Argument nicht in einem Verschluss enthielt
  • Erwartete Expression
  • Zahnspange Block von Anweisungen in einer nicht verwendeten Schließung
+0

Ihre Syntax ist in Ordnung, Sie müssen mehr Code im Zusammenhang mit 'objectDictionaries' zeigen –

+0

versuchen Sie, indem Sie' init (fromDictionary Wörterbuch: [String: Any]) 'in' init (fromDictionary Wörterbuch: [[String: Any]]) 'bcz json ist eine Reihe von dict. Stellen Sie jetzt sicher, dass Ihre Daten durch Drucken von Werten in der Konsole angezeigt werden. –

+0

Welchen Fehler bekommen Sie?Hat Ihre Init-Methode genau diese Signatur? Ist es möglich, dass Sie einen fehlgeleiteten Initialisierer haben? ('init? (...)'), wenn ja, müssen Sie 'flatMap' verwenden. –

Antwort

2

map gibt kein optionales zurück, so dass let children = childDictionaries.map { ChildObject(fromDictionary: $0) } nicht in Ihrer Wächterklausel enthalten sein kann.

Auf der anderen Seite gibt ChildObject(fromDictionary: $0) eine optionale zurück, die map nicht unterstützt.

Sie könnten flatMap verwenden, so Werte, die ignoriert werden kann nicht initialisiert werden:

class ParentObject { 
    let children: [ChildObject] 

    required init?(fromDictionary aDictionary: [String:Any]) { 
     guard let childDictionaries = aDictionary["children"] as? [[String:Any]], 
     else { return nil } 

     self.children = childDictionaries.flatMap { ChildObject(fromDictionary: $0) } 

    } 
} 

Sie können auch Null zurück, wenn alle Kinder richtig initialisiert werden müssen:

required init?(fromDictionary aDictionary: [String:Any]) { 
     guard let childDictionaries = aDictionary["children"] as? [[String:Any]] 
     else { return nil } 

     let children = childDictionaries.flatMap { ChildObject(fromDictionary: $0) } 

     guard children.count == childDictionaries.count else { return nil } 

     self.children = children 
    } 
2

Für beide Klasse haben Sie init? bedeutet, dass es Null zurückgibt, so dass, wenn Sie das Array des Wörterbuchs zuordnen es gibt [ParentObject?] und [ParentObject?] bedeutet Array-Objekt sind optional und Sie versuchen, Ergebnis in Array vongespeichert, um das Problem zu lösen einfach flatMap verwenden, weil Es wird ignored/reduce die nil und geben Sie Array vonObjekte.

class ParentObject { 
    var children: [ChildObject] 

    required init?(fromDictionary aDictionary: [String:Any]) { 
     guard let childDictionaries = aDictionary["children"] as? [[String:Any]] else { 
      return nil 
     } 
     self.children = childDictionaries.flatMap { ChildObject.init } 
    } 

} 

Das Gleiche gilt für Array von ParentObject

self.parents = objectDictionaries.flatMap { ParentObject.init } 

Hinweis: Rückgabetyp von map ist nicht die optional es so entfernen guard let wie ich getan habe.