Created
June 24, 2015 20:09
-
-
Save mackhowell/92b1001497aef5609ce4 to your computer and use it in GitHub Desktop.
swift-book
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
import UIKit | |
// operator overloading | |
func + (left: [Double], right: [Double]) -> [Double] { | |
var sum: [Double] = [] | |
for (n, m) in zip(left, right) { | |
sum.append(n + m) | |
} | |
return sum | |
} | |
[1, 2] + [1, 2] | |
// custom operator | |
infix operator ** { associativity left precedence 160 } | |
func ** (left: Double, right: Double) -> Double { | |
return pow(left, right) | |
} | |
3 ** 3 | |
// custom operator for regex matching | |
protocol RegularExpressionMatchable { | |
func match(pattern: String, options: NSRegularExpressionOptions) -> Bool | |
} | |
extension String: RegularExpressionMatchable { | |
func match(pattern: String, options: NSRegularExpressionOptions) -> Bool { | |
let regex = NSRegularExpression(pattern: pattern, options: options, error: nil) | |
return regex?.numberOfMatchesInString(self, options: nil, range: NSMakeRange(0, count(pattern))) != 0 | |
} | |
} | |
infix operator =~ { associativity left precedence 130 } | |
func =~ <T: RegularExpressionMatchable> (left: T, right: String) -> Bool { | |
return left.match(right, options: nil) | |
} | |
var mack: String = "match something inside this cool string" | |
mack.match("match", options: nil) | |
mack =~ "* cool" | |
mack =~ "cat" | |
// writing generic type structs | |
// called "stack", an ordered set of values | |
// that you can push and pop | |
struct Stack<T> { | |
var items = [T]() | |
mutating func push(item: T) { | |
items.append(item) | |
} | |
mutating func pop() -> T { | |
return items.removeLast() | |
} | |
} | |
var stackOfStrings = Stack<String>() | |
stackOfStrings.push("uno") | |
stackOfStrings.push("dos") | |
let lastValue = stackOfStrings.pop() | |
stackOfStrings.push("tres") | |
// now extend the stack type | |
extension Stack { | |
var topItem: T? { | |
return items.isEmpty ? nil : items[items.count - 1] | |
} | |
} | |
if let topItem = stackOfStrings.topItem { | |
println("top item is \(topItem)") | |
} | |
// Hashtable | |
//struct Dictionary<Key : Hashtable, Value> : CollectionType, DictionaryLiteralConvertible { | |
//} | |
// NSError | |
// Consuming | |
//if let URL = NSURL(string: "www.example.com") { | |
// let request = NSURLRequest(URL: URL) | |
// let session = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration()) | |
// let dataTask = session.dataTaskWithRequest(request) { (data: NSData?, response: NSURLResponse?, error: NSError?) in | |
// if let error = error { | |
// println(error) | |
// } else { | |
// println(response) | |
// } | |
// } | |
// dataTask.resume() | |
//} | |
// Producing... | |
//func validateObject(object: AnyObject, error: NSErrorPointer) -> Bool { | |
// let sucess = validatingMethodThatFails(object) | |
// if !sucess && error != nil { | |
// error.memory = NSError(domain: NSMackErrorDomain, code: -42, userInfo: nil) | |
// } | |
// return sucess | |
//} | |
//var validateError: NSError? | |
//validateObject("BYE!", &validateError) | |
//if let error = validateError { | |
// println(error) | |
//} | |
// Accessing bundle path and URL of file manager | |
let filemanager = NSFileManager.defaultManager() | |
let documentsPath: String? = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentationDirectory, NSSearchPathDomainMask.UserDomainMask, true).first as? String | |
let bundlePath = NSBundle.mainBundle().bundlePath.stringByAppendingPathComponent("Contents/Resources") | |
let bundleURL = NSBundle.mainBundle().bundleURL | |
// List all files | |
let contents = filemanager.contentsOfDirectoryAtURL(bundleURL, includingPropertiesForKeys: nil, options: nil, error: nil) ?? [] | |
for fileUrl in contents { | |
println(fileUrl) | |
} | |
// NSDataDetector // like regex | |
// can be used to match: name, jobtitle, organization, street, | |
// city, state, zip, country, phone, url, flight info | |
let string = "330 Greene Ave. / 415-694-3555" | |
let types: NSTextCheckingType = NSTextCheckingType.Address | NSTextCheckingType.PhoneNumber | |
var error: NSError? | |
let detector = NSDataDetector(types: types.rawValue, error: &error) | |
var results = [AnyObject]() | |
detector!.enumerateMatchesInString(string, options: nil, range: NSMakeRange(0, (string as NSString).length)) { | |
(result, flags, _) in | |
results.append(result) | |
} | |
println(results) | |
// Error handling with enums | |
//enum Result<T> { | |
// case Success(T) | |
// case Failure(String) | |
//} | |
//var result: Double = 2.5 / 3 | |
//switch result { | |
//case .Success(let quotient): | |
// println(quotient) | |
//case .Failure(let errSTring): | |
// println(errSTring) | |
//} | |
// Currency converter piece | |
protocol CurrencySymbol { | |
func symbol() -> String | |
} | |
extension Currency : CurrencySymbol { | |
func symbol() -> String { | |
switch self { | |
case .Eur: return "€" | |
case .Usd: return "$" | |
} | |
} | |
} | |
enum Currency { | |
case Usd | |
case Eur | |
} | |
// Old way (with switch case for each currency) | |
//func symbol(input: Currency) -> String { | |
// switch input { | |
// case .Eur: return "€" | |
// case .Usd: return "$" | |
// } | |
//} | |
// | |
//func format(amount: Double, currency: Currency) -> String { | |
// let formatter = NSNumberFormatter() | |
// formatter.numberStyle = .CurrencyStyle | |
// formatter.currencySymbol = symbol(currency) | |
// return formatter.stringFromNumber(amount)! | |
//} | |
// New way -- allows you to add more currencies down the line! | |
// any type (bitcoin) that conforms to CurrenccySymbol can now be formatted. | |
// open for extension: take in values that conform to a protocol | |
// enums + protocol = expressive api | |
func format(amount: Double, currency: CurrencySymbol) -> String { | |
let formatter = NSNumberFormatter() | |
formatter.numberStyle = .CurrencyStyle | |
formatter.currencySymbol = currency.symbol() | |
return formatter.stringFromNumber(amount)! | |
} | |
struct Bitcoin : CurrencySymbol { | |
func symbol() -> String { | |
return "B⃦" | |
} | |
} | |
format(1000.00, Currency.Eur) | |
format(1000, Bitcoin()) | |
// Functional paradigm stuffs | |
// stop iterating use these | |
let numbers = [1, 2, 3] | |
let squares = numbers.map { | |
$0 * $0 | |
} | |
let odds = numbers.filter { | |
$0 % 2 == 1 | |
} | |
let sum = numbers.reduce(0) { | |
$0 + $1 | |
} | |
// finding if scene is in act one or not | |
let romeoandjuliet = ["Act 1, Scene 1: blah blah", "Act 1, Scene 2: blah blah", "Act 2, Scene 1: blah blah"] | |
// old way: | |
var act1SceneCount = 0 | |
for scene in romeoandjuliet { | |
if scene.hasPrefix("Act 1") { | |
++act1SceneCount | |
} | |
} | |
// new way -- we don't have to manage our own mutable state as in "act1SceneCount" | |
// also the language/compiler handles the looping! | |
func countIfAct1(accumulator: Int, title: String) -> Int { | |
if title.hasPrefix("Act 1") { | |
return accumulator + 1 | |
} else { | |
return accumulator | |
} | |
} | |
let actOneSceneCount = romeoandjuliet.reduce(0, combine: countIfAct1) | |
// or even: | |
let actOneSceneCounttt = romeoandjuliet.reduce(0) { | |
count, title in | |
title.hasPrefix("Act 1") ? count + 1 : count | |
} | |
// blocks can be passed around everyyyywhere in swift | |
// value vs ref | |
// use structs when | |
// - comparing instance data with == makes sense | |
// - you want copies to have independent state | |
// - data will be used across multiple threads | |
// use classes when | |
// - comparing instance identity with === makes sense | |
// - you want to make shared, mutable state | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment