Last active
April 8, 2017 12:51
-
-
Save ijoshsmith/ee472ee30bb1f9bb17c6 to your computer and use it in GitHub Desktop.
Higher-order functions in Swift
This file contains hidden or 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
// | |
// main.swift | |
// HigherOrderFunctions | |
// | |
// Created by Joshua Smith on 12/6/15. | |
// Copyright © 2015 iJoshSmith. All rights reserved. | |
// | |
/* | |
This file contains simple implementations of several | |
higher-order functions in the Swift standard library. | |
These functions are not intended for production usage. | |
Always use the Swift standard library implementations. | |
*/ | |
import Foundation | |
// Reduce | |
func _reduce<Element, Result>( | |
elements: [Element], | |
initial: Result, | |
combine: (accumulator: Result, element: Element) -> Result) | |
-> Result | |
{ | |
var acc = initial | |
for elem in elements { | |
acc = combine(accumulator: acc, element: elem) | |
} | |
return acc | |
} | |
let sum = _reduce([1, 2, 3], initial: 0) { (acc, elem) in | |
acc + elem | |
} | |
print("sum = \(sum)") // prints: sum = 6 | |
// Filter | |
func _filter<Element>(elements: [Element], include: Element -> Bool) -> [Element] | |
{ | |
return _reduce(elements, initial: [Element]()) { (acc, elem) in | |
include(elem) ? acc + [elem] : acc | |
} | |
} | |
let evens = _filter([1, 2, 3]) { elem in | |
elem % 2 == 0 | |
} | |
print("evens = \(evens)") // prints: evens = [2] | |
// Map | |
func _map<Element, Result>(elements: [Element], transform: Element -> Result) -> [Result] | |
{ | |
return _reduce(elements, initial: [Result]()) { (acc, elem) in | |
acc + [transform(elem)] | |
} | |
} | |
let strings = _map([1, 2, 3]) { elem in String(elem) } | |
print("strings = \(strings)") // prints: strings = ["1", "2", "3"] | |
// Flat Map for optionals | |
func _flatMap<Element, Result>(elements: [Element], transform: Element -> Result?) -> [Result] | |
{ | |
return _reduce(elements, initial: [Result]()) { (acc, elem) in | |
if let result = transform(elem) { | |
return acc + [result] | |
} | |
else { | |
return acc | |
} | |
} | |
} | |
let nonNils = _flatMap([1, nil, 3]) { $0 } | |
print("nonNils = \(nonNils)") // prints: nonNils = [1, 3] | |
// Flat Map for sequences | |
func _flatMap<SeqElement: SequenceType, Result: SequenceType>( | |
elements: [SeqElement], transform: [SeqElement.Generator.Element] -> Result) | |
-> [Result.Generator.Element] | |
{ | |
let accumulator = Array<Result.Generator.Element>() | |
return _reduce(elements, initial: accumulator) { (acc, elem) in | |
return acc + transform(elem as! [SeqElement.Generator.Element]) | |
} | |
} | |
let singleValues: [Int] = _flatMap([ [1], [2, 3], [], [4] ]) { array in | |
return array.count == 1 ? array : [] | |
} | |
print("singleValues = \(singleValues)") // print: singleValues = [1, 4] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is the code sample for a blog post:
http://ijoshsmith.com/2015/12/09/higher-order-functions-in-swift/