Last active
August 29, 2015 14:22
-
-
Save ilyannn/719a733bdd85492365bd to your computer and use it in GitHub Desktop.
Erica's code challenge
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
// For https://gist.github.com/erica/5477d5caccfbff04a802 | |
// MARK: Generic collections | |
import Foundation | |
import Swift | |
infix operator ➜ { associativity left } | |
func ➜(source: [String], f: (String) -> ()) -> () { | |
for element in source { | |
f(element) | |
} | |
} | |
func ➜<T, U>(source: [T], f: (T) -> U?) -> [U] { | |
var results: [U] = [] | |
for element in source { | |
if let result = f(element) { | |
results.append(result) | |
} | |
} | |
return results | |
} | |
func ➜<T, U>(source: [T], f: (T) -> (() -> U?)) -> [U] { | |
return source ➜ { f($0) } | |
} | |
// MARK: JSONs | |
// This is incomplete! We just test the syntax. | |
extension NSURL { | |
func fetchJSON() -> JSON? { | |
return JSON() | |
} | |
} | |
class JSON { | |
func arrayValue(key:String) -> [JSON] { | |
return [] | |
} | |
func stringValue(key:String) -> String? { | |
return "" | |
} | |
func intValue(key:String) -> Int? { | |
return 0 | |
} | |
} | |
func usingFirst<T>(extractor: JSON -> (() -> T?)) -> (JSON -> T?) { | |
return { json in | |
if let result = json.arrayValue("results").first { | |
return extractor(result)() | |
} | |
return nil; | |
} | |
} | |
// MARK: Specific models | |
struct Price { | |
let name: String | |
let formattedPrice: String | |
} | |
struct Rating { | |
let name: String | |
let stars: Int? | |
} | |
private extension JSON { | |
func extractPrice() -> Price? { | |
if let name = stringValue("trackName"), | |
price = stringValue("formattedPrice") | |
{ | |
return Price(name: name, formattedPrice: price) | |
} | |
return nil; | |
} | |
func extractRating() -> Rating? { | |
if let name = stringValue("trackName") { | |
// Rating keys vary by content type | |
return Rating(name: name, stars: intValue("averageUserRating") | |
?? intValue("trackContentRating") ) | |
} | |
return nil | |
} | |
} | |
// MARK: Query URL | |
func FetchQueryURL(string: String) -> NSURL? { | |
return NSURL(string: string) | |
} | |
// MARK: Main functions | |
func ShowPrices(productURLStrings: [String]) { | |
println("Today's prices") | |
productURLStrings | |
➜ FetchQueryURL | |
➜ NSURL.fetchJSON | |
➜ usingFirst(JSON.extractPrice) | |
➜ { "\($0.name): \($0.formattedPrice)" } | |
➜ println | |
println() | |
} | |
func CheckRatings(productURLStrings: [String]) { | |
println("Checking ratings") | |
// productURLStrings | |
// ➜ FetchQueryURL | |
// ➜ NSURL.fetchJSON | |
// ➜ usingFirst(JSON.extractRating) | |
// ➜ { "\($0.name): \($0.starDescription)" } | |
// ➜ println | |
// | |
productURLStrings | |
➜ FetchQueryURL | |
➜ NSURL.fetchJSON | |
➜ usingFirst(JSON.extractRating) | |
// More complex blocks than { "\($0.name): \($0.starDescription)" } can be supplied. | |
// Although for some reason Xcode is not able to infer this closure's type. | |
➜ { (rating: Rating) -> String? in | |
var desc = "ratings not available" | |
map(rating.stars) { desc = "\($0) stars" } | |
return rating.name + " " + desc | |
} | |
➜ println | |
println() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment