Skip to content

Instantly share code, notes, and snippets.

@ilyannn
Last active August 29, 2015 14:22
Show Gist options
  • Save ilyannn/719a733bdd85492365bd to your computer and use it in GitHub Desktop.
Save ilyannn/719a733bdd85492365bd to your computer and use it in GitHub Desktop.
Erica's code challenge
// 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