{"action":"created","issue":{"url":"https://api.github.com/repos/hkellaway/Gloss/issues/221","repository_url":"https://api.github.com/repos/hkellaway/Gloss","labels_url":"https://api.github.com/repos/hkellaway/Gloss/issues/221/labels{/name}","comments_url":"https://api.github.com/repos/hkellaway/Gloss/issues/221/comments","events_url":"https://api.github.com/repos/hkellaway/Gloss/issues/221/events","html_url":"https://github.com/hkellaway/Gloss/issues/221","id":179649100,"number":221,"title":"Array decoding partial success?","user":{"login":"ryanschneider","id":53520,"avatar_url":"https://avatars.githubusercontent.com/u/53520?v=3","gravatar_id":"","url":"https://api.github.com/users/ryanschneider","html_url":"https://github.com/ryanschneider","followers_url":"https://api.github.com/users/ryanschneider/followers","following_url":"https://api.github.com/users/ryanschneider/following{/other_user}","gists_url":"https://api.github.com/users/ryanschneider/gists{/gist_id}","starred_url":"https://api.github.com/users/ryanschneider/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ryanschneider/subscriptions","organizations_url":"https://api.github.com/users/ryanschneider/orgs","repos_url":"https://api.github.com/users/ryanschneider/repos","events_url":"https://api.github.com/users/ryanschneider/events{/privacy}","received_events_url":"https://api.github.com/users/ryanschneider/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/hkellaway/Gloss/labels/question","name":"question","color":"cc317c"}],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":2,"created_at":"2016-09-28T00:13:24Z","updated_at":"2016-09-28T17:39:19Z","closed_at":"2016-09-28T13:05:22Z","body":"Previously with 0.7.x, I could decode an array and get back all the items that passed decoding.\r\n\r\nFor example, if I had the JSON:\r\n\r\n```json\r\n{ \"values\": [ { \"value\": 4 }, { \"value\": null }  ] }\r\n```\r\n\r\nAnd wanted to decode that into a struct like so:\r\n\r\n```swift\r\nstruct Item : Glossy {\r\n   let value: Int\r\n}\r\n\r\nfunc decode(json: JSON) -> [Item] {\r\n    return \"values\" <~~ json\r\n}\r\n```\r\n\r\nThat would return `[ { value: 4 } ]`.  With 1.0, it returns `nil`, because of this change to `decode(decodableArrayForKey)`:\r\n\r\n```swift\r\n                for subJSON in jsonArray {\r\n                    guard let model = T(json: subJSON) else {\r\n                        return nil  /// Previously this was an if let, not a guard\r\n                    }\r\n                    \r\n                    models.append(model)\r\n                }\r\n```\r\n\r\nI think that returning nil is the best default, but was wondering if there's an easy way to simulate 0.7.x behavior? \r\n\r\nTurns out one of the server endpoints I communicate with is giving back `null`s that I never noticed because of 0.7.x's behavior (which is why I approve of the change for 1.0 :) ), but want to simulate the old behavior on the client until I can update the server.  Since `null` isn't intended, I'd rather not change my struct to make the value Optional.\r\n\r\nWould the easiest route be for me to write an extension method that simulates 0.7 behavior, something like:\r\n\r\n```swift\r\nextension Decoder {\r\n    static func decodePartialArray<T>(key: String) -> [T] {\r\n        // more or less copy/paste the 0.7 code in here\r\n    }\r\n}\r\n```\r\n\r\nFor 1.1, what do you think of adding a `<~~!` or other operator that emulates the old behavior?\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/hkellaway/Gloss/issues/comments/250240887","html_url":"https://github.com/hkellaway/Gloss/issues/221#issuecomment-250240887","issue_url":"https://api.github.com/repos/hkellaway/Gloss/issues/221","id":250240887,"user":{"login":"ryanschneider","id":53520,"avatar_url":"https://avatars.githubusercontent.com/u/53520?v=3","gravatar_id":"","url":"https://api.github.com/users/ryanschneider","html_url":"https://github.com/ryanschneider","followers_url":"https://api.github.com/users/ryanschneider/followers","following_url":"https://api.github.com/users/ryanschneider/following{/other_user}","gists_url":"https://api.github.com/users/ryanschneider/gists{/gist_id}","starred_url":"https://api.github.com/users/ryanschneider/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ryanschneider/subscriptions","organizations_url":"https://api.github.com/users/ryanschneider/orgs","repos_url":"https://api.github.com/users/ryanschneider/repos","events_url":"https://api.github.com/users/ryanschneider/events{/privacy}","received_events_url":"https://api.github.com/users/ryanschneider/received_events","type":"User","site_admin":false},"created_at":"2016-09-28T17:39:19Z","updated_at":"2016-09-28T17:39:19Z","body":"Thanks for the feedback (and a great framework in general!).  I agree with keeping the operators focused, so opted not to implement my own either.\r\n\r\nAnd for future reference in case anyone else runs into the same issue, here's my extension:\r\n\r\n```swift\r\nextension Decoder {\r\n    /**\r\n     Decodes JSON to a Decodable object array.  Emulates pre-0.8 behavior\r\n     where elements of the JSON array that cannot be converted to T are skipped instead\r\n     of returning nil.\r\n\r\n     - parameter decodePartialArrayForKey: Key used in JSON for decoded value.\r\n\r\n     - returns: Array of values that could be decoded from JSON, or nil if key is not found.\r\n     */\r\n    public static func decode<T: Decodable>(decodePartialArrayForKey key: String) -> (JSON) -> [T]? {\r\n        return {\r\n            json in\r\n\r\n            if let jsonArray = json[key] as? [JSON] {\r\n                var models: [T] = []\r\n\r\n                for subJSON in jsonArray {\r\n                    if let model = T(json: subJSON) {\r\n                        models.append(model)\r\n                    }\r\n                }\r\n\r\n                return models\r\n            }\r\n\r\n            return nil\r\n        }\r\n    }\r\n}\r\n```\r\n\r\nUsage like so:\r\n```swift\r\n// Replace:\r\nlet arr: [Value]? = \"values\" <~~ json\r\n// With:\r\nlet arr: [Value]? = Decoder.decode(decodePartialArrayForKey: \"values\")(json)\r\n```"}}
{"actor":{"display_login":"ryanschneider"}}