Last active
August 29, 2015 14:12
-
-
Save BestKora/d4aac272917c72ce8b44 to your computer and use it in GitHub Desktop.
Код к статье Chris Eidhof "JSON parsing in Swift" http://chris.eidhof.nl/posts/json-parsing-in-swift.html с улучшенной функцией печати на Playground.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This code accompanies a blog post: http://chris.eidhof.nl/posts/json-parsing-in-swift.html | |
// | |
// As the >>= operator is already defined, so I changed it to >>>= | |
import Foundation | |
let parsedJSON : [String:AnyObject] = [ | |
"stat": "ok", | |
"blogs": [ | |
"blog": [ | |
[ | |
"id" : 73, | |
"name" : "Bloxus test", | |
"needspassword" : true, | |
"url" : "http://remote.bloxus.com/" | |
], | |
[ | |
"id" : 74, | |
"name" : "Manila Test", | |
"needspassword" : false, | |
"url" : "http://flickrtest1.userland.com/" | |
] | |
] | |
] | |
] | |
struct Blog { | |
let id: Int | |
let name: String | |
let needsPassword : Bool | |
let url: NSURL | |
} | |
func parseBlog(blog: AnyObject) -> Blog? { | |
let mkBlog = curry {id, name, needsPassword, url in Blog(id: id, name: name, needsPassword: needsPassword, url: url) } | |
return asDict(blog) >>>= { | |
mkBlog <*> int($0,"id") | |
<*> string($0,"name") | |
<*> bool($0,"needspassword") | |
<*> (string($0, "url") >>>= toURL) | |
} | |
} | |
func parseJSON() { | |
let blogs = dictionary(parsedJSON, "blogs") >>>= { | |
array($0, "blog") >>>= { | |
join($0.map(parseBlog)) | |
} | |
} | |
printBlogs(blogs) | |
} | |
extension Blog : Printable { | |
var description : String { | |
return "Blog { id = \(id), name = \(name), needsPassword = \(needsPassword), url = \(url)" | |
} | |
} | |
func toURL(urlString: String) -> NSURL { | |
return NSURL(string: urlString)! | |
} | |
func asDict(x: AnyObject) -> [String:AnyObject]? { | |
return x as? [String:AnyObject] | |
} | |
func join<A>(elements: [A?]) -> [A]? { | |
var result : [A] = [] | |
for element in elements { | |
if let x = element { | |
result += [x] | |
} else { | |
return nil | |
} | |
} | |
return result | |
} | |
infix operator <*> { associativity left precedence 150 } | |
func <*><A, B>(l: (A -> B)?, r: A?) -> B? { | |
if let l1 = l { | |
if let r1 = r { | |
return l1(r1) | |
} | |
} | |
return nil | |
} | |
func flatten<A>(x: A??) -> A? { | |
if let y = x { return y } | |
return nil | |
} | |
func array(input: [String:AnyObject], key: String) -> [AnyObject]? { | |
let maybeAny : AnyObject? = input[key] | |
return maybeAny >>>= { $0 as? [AnyObject] } | |
} | |
func dictionary(input: [String:AnyObject], key: String) -> [String:AnyObject]? { | |
return input[key] >>>= { $0 as? [String:AnyObject] } | |
} | |
func string(input: [String:AnyObject], key: String) -> String? { | |
return input[key] >>>= { $0 as? String } | |
} | |
func number(input: [NSObject:AnyObject], key: String) -> NSNumber? { | |
return input[key] >>>= { $0 as? NSNumber } | |
} | |
func int(input: [NSObject:AnyObject], key: String) -> Int? { | |
return number(input,key).map { $0.integerValue } | |
} | |
func bool(input: [NSObject:AnyObject], key: String) -> Bool? { | |
return number(input,key).map { $0.boolValue } | |
} | |
func curry<A,B,R>(f: (A,B) -> R) -> A -> B -> R { | |
return { a in { b in f(a,b) } } | |
} | |
func curry<A,B,C,R>(f: (A,B,C) -> R) -> A -> B -> C -> R { | |
return { a in { b in {c in f(a,b,c) } } } | |
} | |
func curry<A,B,C,D,R>(f: (A,B,C,D) -> R) -> A -> B -> C -> D -> R { | |
return { a in { b in { c in { d in f(a,b,c,d) } } } } | |
} | |
infix operator >>>= {} | |
func >>>= <A,B> (optional : A?, f : A -> B?) -> B? { | |
return flatten(optional.map(f)) | |
} | |
//---------------------Новые операторы -------- | |
// Для извлечения словаря | |
infix operator |> { associativity left precedence 150 } | |
func |>(input: [String:AnyObject]?, key: String) -> [String:AnyObject]? { | |
return input![key] >>>= { $0 as? [String:AnyObject] } | |
} | |
// Для извлечения массива | |
infix operator ||> { associativity left precedence 150 } | |
func ||>(input: [String:AnyObject]?, key: String) -> [AnyObject]? { | |
return input![key] >>>= { $0 as? [AnyObject] } | |
} | |
//------------------------------------------------- | |
func printBlogs(blogs:[Blog]?){ | |
switch blogs { | |
case .Some (let a): | |
println(a.reduce("", {$0 + $1.description + "\n"} )) | |
default: return () | |
} | |
} | |
func parseJSON1() { | |
let blogs = parsedJSON |> "blogs" ||> "blog" >>>= {join($0.map(parseBlog))} | |
printBlogs(blogs) | |
} | |
parseJSON() | |
parseJSON1() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment