Skip to content

Instantly share code, notes, and snippets.

@mackhowell
Created June 24, 2015 20:09
Show Gist options
  • Save mackhowell/92b1001497aef5609ce4 to your computer and use it in GitHub Desktop.
Save mackhowell/92b1001497aef5609ce4 to your computer and use it in GitHub Desktop.
swift-book
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