Skip to content

Instantly share code, notes, and snippets.

@iamvery
Last active August 29, 2015 14:16
Show Gist options
  • Save iamvery/05ba0bc82091aade5f69 to your computer and use it in GitHub Desktop.
Save iamvery/05ba0bc82091aade5f69 to your computer and use it in GitHub Desktop.
Extend Swift's Array#reduce behavior to provide reasonable initial values
extension Array {
func deduce (initial: T? = nil, _ combine: (T, T) -> T) -> T? {
if let initial = initial {
return reduce(initial, combine: combine);
}
if count > 1 {
var rest = self[1..<count]
return rest.reduce(first!, combine: combine)
} else {
return first
}
}
}
protocol Constructable {
init()
}
extension String: Constructable {}
extension Int: Constructable {}
extension Array {
func deduce_ <U: Constructable> (initial: U = U(), _ combine: (U, T) -> U) -> U {
return reduce(initial, combine: combine)
}
}
var a = [1,2,3]
assert(a.reduce(0, combine: +) == 6)
assert(a.deduce(initial: 1, +) == 7)
assert(a.deduce(+) == 6)
assert([Int]().deduce(+) == nil)
assert([1].deduce(+) == 1)
assert(a.deduce_(initial: 1, +) == 7)
assert(a.deduce_(+) == 6)
assert([Int]().deduce_(+) == 0) // the behavior is differnt than deduce above
assert([1].deduce_(+) == 1)
var b = ["a", "b", "c"]
assert(b.deduce_(+) == "abc")
assert(b.deduce_(initial: "!", +) == "!abc")
assert(a.deduce_ { $0 + String($1) } == "123")
extension Int {
init(_ strValue: String) {
var value = strValue.toInt()
self.init(value ?? 0)
}
}
assert(["1", "2", "3", "a"].deduce_ { $0 + Int($1) } == 6) // :mindblown:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment