Skip to content

Commit

Permalink
Merge pull request #17 from alickbass/flatMap-array
Browse files Browse the repository at this point in the history
Flat map array
  • Loading branch information
Oleksii Dykan authored Feb 20, 2017
2 parents 867e010 + 1a63362 commit 8265da1
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 2 deletions.
24 changes: 22 additions & 2 deletions SwiftyJSONModel/JSONObject.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public extension JSONObject where PropertyType.RawValue == String {
return try value(for: keyPath)
}

public func value<T: JSONInitializable>(for keyPath: [PropertyType]) throws -> T {
private func value<T: JSONInitializable>(for keyPath: [PropertyType]) throws -> T {
assert(keyPath.isEmpty == false, "KeyPath cannot be empty")

let key = keyPath[0]
Expand All @@ -75,7 +75,7 @@ public extension JSONObject where PropertyType.RawValue == String {
return try value(for: keyPath)
}

public func value<T: JSONInitializable>(for keyPath: [PropertyType]) throws -> [T] {
private func value<T: JSONInitializable>(for keyPath: [PropertyType]) throws -> [T] {
assert(keyPath.isEmpty == false, "KeyPath cannot be empty")

let key = keyPath[0]
Expand All @@ -97,6 +97,26 @@ public extension JSONObject where PropertyType.RawValue == String {
}
}

public func flatMap<T: JSONInitializable>(for keyPath: PropertyType...) throws -> [T] {
return try flatMap(for: keyPath)
}

private func flatMap<T: JSONInitializable>(for keyPath: [PropertyType]) throws -> [T] {
assert(keyPath.isEmpty == false, "KeyPath cannot be empty")

let key = keyPath[0]
do {
if keyPath.count == 1 {
return try self[key].arrayValue().lazy.flatMap({ try? T(json: $0) })
} else {
let subPath: [PropertyType] = .init(keyPath[1..<keyPath.count])
return try JSONObject<PropertyType>(json: self[key]).flatMap(for: subPath)
}
} catch let error as JSONModelError {
throw JSONModelError.invalidValueFor(key: key.rawValue, error)
}
}

// MARK: - Optional methods
public func value<T: JSONInitializable>(for keyPath: PropertyType...) -> T? {
return try? value(for: keyPath)
Expand Down
18 changes: 18 additions & 0 deletions SwiftyJSONModelTests/JSONObjectTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -124,4 +124,22 @@ class JSONObjectTests: XCTestCase {
XCTAssertEqual((object.value(for: .first, .second, .array) as [Int]?)!, [1, 2, 3])
XCTAssertNil(object.value(for: .first, .second, .array) as [String]?)
}

func testJSONObjectFlatMap() {
enum PropertyKey: String {
case first, second, third, array
}

let nestedJSON: JSON = ["first": ["second": ["third": 3, "array": [1, "test", 3]]]]
let object = try! JSONObject<PropertyKey>(json: nestedJSON)

XCTAssertEqual(try! object.flatMap(for: .first, .second, .array), [1, 3])
XCTAssertEqual(try! object.flatMap(for: .first, .second, .array), ["test"])
XCTAssertThrowsError(try object.flatMap(for: .first, .second, .third) as [Int]) { error in
let first = PropertyKey.first.rawValue
let second = PropertyKey.second.rawValue
let third = PropertyKey.third.rawValue
XCTAssertEqual(error as? JSONModelError, .invalidValueFor(key: first, .invalidValueFor(key: second, .invalidValueFor(key: third, .invalidElement))))
}
}
}

0 comments on commit 8265da1

Please sign in to comment.