bignerdranch / Freddy

A reusable framework for parsing JSON in Swift.
MIT License
1.09k stars 120 forks source link

request: make getArray(from:) and decodedArray(from:) public #232

Closed mlilback closed 7 years ago

mlilback commented 7 years ago

The static function getArray(from) would very useful in cases where the root json item is an array, ([ "foo", "bar" ]). Also, decodedArray(from:) would also be useful.

I see no way to accomplish decoded an array that is not part of an object, and I'm littering my code with

if case .array(let array) = json { 
    let objs = array.map { MyObject(json: $0) }
    //do something with objs
}

which is exactly what the internal static function decodedArray(from:) does.

mdmathias commented 7 years ago

I think you are looking for

/// Attempts to decode many values from a descendant JSON array at a path
/// into JSON.
/// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
/// - parameter type: If the context this method is called from does not
///                   make the return type clear, pass a type implementing `JSONDecodable`
///                   to disambiguate the type to decode with.
/// - returns: An `Array` of decoded elements
/// - throws: One of the `JSON.Error` cases thrown by `decode(at:type:)`, or
///           any error that arises from decoding the contained values.
/// - seealso: `JSON.decode(at:type:)`
public func decodedArray<Decoded: JSONDecodable>(at path: JSONPathType..., type: Decoded.Type = Decoded.self) throws -> [Decoded] {
    return try JSON.decodedArray(from: value(at: path))
}

If the array that you are trying to decode is at the top level, then you can omit the path like so:

let jsonArray = [1,2,3,4] as JSON
do {
    let intArray = try jsonArray.decodedArray(type: Int.self)
    print([1,2,3,4] == intArray)
} catch {
    print("Not equal")
}

Make sure to take a look at our tests for further examples like this.