map, reduce and filter in swift
TRANSCRIPT
Map, Reduce and Filter in Swift
Aleksandras Smirnovas, coder.lt Cocoa.lt #2, 2015
Agenda
• What is functional programming?
• Swift 101
• Examples of unfunctional to functional code
Functional Programming
is a programming paradigm—a style of building the structure and elements of computer programs—that treats computation as the evaluation of mathematical functions and avoids changing-state and mutable data.
http://en.wikipedia.org/wiki/Functional_programming
Functional Languages• Haskell
• Skala
• F#
• Erlang
• Clojure
Key concepts• First-class and higher-order functions
• Pure functions
• Recursion
• Functional programming in non-functional languages
http://en.wikipedia.org/wiki/Functional_programming
Swift 101: Function types
func sum(x: Int, y: Int) -> (Int) { return x + y }
Swift 101: Function types
(Int, Int) -> (Int)
Swift 101: Passing and returning functions
func calculator () -> ((Int, Int) -> Int) {
func sum(x: Int, y: Int) -> (Int) { return x + y }
return sum
} let sum = calculator()
sum(5, 6)
Swift 101: Closure {()->() in}
{ (params) -> returnType in statements }
Basic F-programming toolkit
• map
• reduce
• filter
Map
func map<U>(transform: T -> U) -> Array<U>
Return an Array containing the results of calling `transform(x)` on each element x of self
Map on collections
let list = ["c", "d", "a", "b"]
var uppercasedList = [String]()
for char in list { uppercasedList.append(char.uppercaseString) }
Map on collections
let list = ["c", "d", "a", "b"]
let uppercasedList = list.map ({ (char: String) -> String in char.uppercaseString
})
Map on collections
let list = ["c", "d", "a", "b"]
let uppercasedList = list.map ({$0.uppercaseString})
Map on collections
let list = ["c", "d", "a", "b"]
let uppercasedList = list.map {$0.uppercaseString}
FlatMap
func flatMap(transform: T -> [U]) ->[U]
Return an Array containing the results of calling `transform(x)` on each element x of flattening self
FlatMap
let multiList = [["c", "d"], ["a"], ["b"]] var uppercasedMultiList = multiList .flatMap{ $0 } .map {$0.uppercaseString}
Map on optionals
func increment(oNumber: Int?) -> Int? { if let number = oNumber { return number + 1 } else { return nil } }
increment(10) //11 increment(nil) // nil
Map on optionals
func increment(oNumber: Int?) -> Int? { return oNumber.map { number in number + 1 } }
increment(10) //11 increment(nil) // nil
Map on optionals
func increment(oNumber: Int?) -> Int? { return oNumber.map { $0 + 1 } }
increment(10) //11 increment(nil) // nil
Reduce
func reduce(initial: U, combine: (U, T) -> U) -> U
Return the result of repeatedly calling `combine` with an accumulated value initialised to `initial` and each
element of self
Reduce
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
var sum = 0
for i in numbers { sum += i }
Reduce
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let sum = numbers.reduce(0, combine: { (total, number) in return total + number
})
Reduce
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let sum = numbers.reduce(0) { (total, number) in return total + number
}
Reduce
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let sum = numbers.reduce(0) { (total, number) in total + number
}
Reduce
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let sum = numbers.reduce(0) { $0 + $1 }
Reduce
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let sum = numbers.reduce(0, +}
Filter
func filter(includeElement: T -> Bool) -> [T]
Return an Array containing the elements x of self for which `includeElement(x)` is true
Filter
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let evenNumbers = numbers .filter { $0 % 2 == 0 }
Map Filter reduce
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let iEvenSum = numbers .map { $0 + 1 } .filter { $0 % 2 == 0 } .reduce(0, +)
Further Topics
• Function Composition
• Custom operators
• Curried functions
• Functors, Applicative Functors, and Monads
Further Topicstypealias Filter = CIImage -> CIImage
infix operator >>> { associativity left }
func >>> (filter1: Filter, filter2: Filter) -> Filter { return {img in filter2(filter1(img))} }
let myFilter = blur(blurRadius) >>> colorOverlay(overlayColor)
let result = myFilter(image)
http://www.objc.io/books/
Resources• http://www.functionalvilnius.lt
• http://www.haskell.org/haskellwiki/Haskell
• http://learnyouahaskell.com
• http://www.objc.io/books/
• https://github.com/typelift/Swiftz
Thank you
Questions?
@saleksandras