Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Higher-order functions in Swift
//
// 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]
@ijoshsmith

This comment has been minimized.

Copy link
Owner Author

commented Dec 10, 2015

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.