Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Decoding array of arrays #174

Closed
oronbz opened this issue Mar 28, 2017 · 4 comments
Closed

Decoding array of arrays #174

oronbz opened this issue Mar 28, 2017 · 4 comments
Labels

Comments

@oronbz
Copy link

oronbz commented Mar 28, 2017

Hi,
I have an issue decoding array of arrays,
how would you write a decode function which decode a JSON like this:

"summary": {
  "items": [[0], [1], [2]]
}

I've tried writing a struct like this:

struct Summary {
  let items: [[Int]]
}

and an extension:

extension Summary: Decodable {
  static func decode(_ e: Extractor) throws -> Summary {
    return try Summary(items: e <|| "items")
  }
}

but I'm getting an error:
Type '[Int]' does not conform to protocol 'Decodable'

I know the JSON could be built better but this is what I'm getting from the server and this is what I have to decode.

Thanks,
Oron

@toshi0383
Copy link

toshi0383 commented Apr 1, 2017

I ended up writing this code.

infix operator <||<|| : MultiplicationPrecedence

/// - Throws: DecodeError or an arbitrary ErrorType
public func <||<|| <T: Decodable>(e: Extractor, keyPath: KeyPath) throws -> [[T]] {
    let json: [String: Any] = try castOrFail(e.rawValue)
    let array: [Any] = try castOrFail(json[keyPath.components.joined(separator: ".")])
    return try array.map { c -> [T] in
        return try castOrFail(c)
    }
}

I would add this to your App, rather than to Himotoki. I think it's better to keep the core code small.

I also needed to add Optional version of castOrFail to suppress the warning that says Expression implicitly coerced from 'Any?' to Any.

public func castOrFail<T>(_ any: Any?) throws -> T {
    guard let result = any as? T else {
        throw typeMismatch("\(T.self)", actual: any)
    }
    return result
}

So now you can do this.

extension Summary: Decodable {
  static func decode(_ e: Extractor) throws -> Summary {
    return try Summary(items: e <||<|| "items")
  }
}

@ikesyo ikesyo added the question label Apr 1, 2017
@ikesyo
Copy link
Owner

ikesyo commented Apr 1, 2017

Sorry for the late response, and thanks to @toshi0383 for sharing your way!

Seems that this is a duplicate of #149 and I'd rather write something like this: #149 (comment).

@toshi0383
Copy link

Wow, that looks neat😮

@oronbz
Copy link
Author

oronbz commented Apr 1, 2017

Thank you both guys, I'll have a look at both solutions

@ikesyo ikesyo closed this as completed May 27, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants