Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
[
{
"name": {
"first_name": "Lex",
"last_name": "Luthor"
},
"age": 28,
"gender": "male",
"address": {
"street": "244 Clifton Place",
"city": "Edneyville",
"state": "Maine"
},
"skills": [
"laboris",
"id",
"consectetur",
"duis",
"incididunt",
"eiusmod"
]
},
{
"name": {
"first_name": "Ada",
"last_name": "Stuart"
},
"age": 29,
"gender": "female",
"address": {
"street": "754 Marconi Place",
"city": "Rosburg",
"state": "Louisiana"
},
"skills": [
"laborum",
"et",
"proident",
"dolor",
"exercitation",
"nisi"
]
},
{
"name": {
"first_name": "Judith",
"last_name": "Roach"
},
"age": 24,
"gender": "female",
"address": {
"street": "675 Reed Street",
"city": "Cochranville",
"state": "Pennsylvania"
},
"skills": [
"Lorem",
"do",
"commodo",
"occaecat"
]
},
{
"name": {
"first_name": "Jana",
"last_name": "Decker"
},
"age": 21,
"gender": "female",
"address": {
"street": "524 Bridge Street",
"city": "Gila",
"state": "New Hampshire"
},
"skills": [
"sit",
"irure",
"duis",
"sit"
]
},
{
"name": {
"first_name": "Lydia",
"last_name": "Maxwell"
},
"age": 31,
"gender": "female",
"address": {
"street": "596 Folsom Place",
"city": "Galesville",
"state": "Oklahoma"
},
"skills": [
"sunt",
"et",
"et",
"ullamco",
"est",
"ipsum",
"laborum"
]
}
]
struct Customer {
let name: String // first_name, last_name
let age: Int
let gender: Gender
let address: Address
let skills: [String]
}
enum Gender {
case Unknown, Male, Female
}
struct Address {
let street: String
let city: String
let state: String
}
func makeAddress(street: String) -> (city: String) -> (state: String) -> Address {
return { city in { state in
return Address(street: street, city: city, state: state)
}}
}
func makeCustomer(name: String) -> (age: Int) -> (gender: Gender) -> (address: Address) -> (skills: [String]) -> Customer {
return { age in { gender in { address in { skills in
return Customer(name: name, age: age, gender: gender, address: address, skills: skills)
}}}}
}
func get<T>(box:[String: AnyObject], key: String) -> T? {
return box[key] as? T
}
func get<T>(item: AnyObject) -> T? {
return item as? T
}
import Foundation
guard let data = NSData(contentsOfFile: "customers.json"),
let jsonData = try? NSJSONSerialization.JSONObjectWithData(data, options: []) else {
print("Couldn't load JSON file")
exit(1)
}
func parseGender(gender: String) -> Gender {
switch gender {
case "male":
return .Male
case "female":
return .Female
default:
return .Unknown
}
}
func parseName(data: [String: AnyObject]) -> String? {
return ["first_name", "last_name"].map{ data[$0] as? String }
.flatMap{ $0 }
.joinWithSeparator(", ")
}
func parseAddress(data: [String: AnyObject]) -> Address? {
return makeAddress <*> get(data, key: "street")
<*> get(data, key: "city")
<*> get(data, key: "state")
}
func parseCustomer(data: [String: AnyObject]) -> Customer? {
return makeCustomer <*> get(data, key: "name") <~~ parseName
<*> get(data, key: "age")
<*> get(data, key: "gender") <~~ parseGender
<*> get(data, key: "address") <~~ parseAddress
<*> get(data, key: "skills")
}
let customers = get(jsonData) <<~ parseCustomer
guard let customers = customers else {
print("Couldn't parse customers")
exit(1)
}
print(customers)
infix operator <*> {
associativity left
precedence 100
}
infix operator <~~ {
associativity left
precedence 110
}
infix operator <<~ {
associativity left
precedence 110
}
func <*><A, B>(f: (A -> B)?, x: A?) -> B? {
guard let f = f, x = x else {
return nil
}
return f(x)
}
func <~~<A, B>(x: A?, f: (A -> B?)) -> B? {
guard let x = x else {
return nil
}
return f(x)
}
func <<~<A, B>(x: [A]?, f: (A -> B?)) -> [B]? {
guard let x = x else {
return nil
}
return x.map(f).flatMap{ $0 }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment