Last active
September 24, 2020 06:59
-
-
Save fwgreen/9a83dc86dd1028b96215a3ae01df5041 to your computer and use it in GitHub Desktop.
Simple utility extensions for Swift
This file contains 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
///Scan function that starts with the first element of the Sequence, like fold | |
extension Sequence { | |
func scan(_ combiner: (Element, Element) throws -> Element) rethrows -> [Element] { | |
var iterator = makeIterator() | |
guard let initial = iterator.next() else { | |
return [] | |
} | |
var firstIteration = true | |
var accumulator = initial | |
return try map { element in | |
if firstIteration == true { | |
firstIteration = false | |
return initial | |
} else { | |
accumulator = try combiner(accumulator, element) | |
return accumulator | |
} | |
} | |
} | |
func scan(_ initial: Element, _ combiner: (Element, Element) throws -> Element) rethrows -> [Element] { | |
var accumulator = initial | |
let sequence = [initial] + self | |
return try sequence.map { element in | |
accumulator = try combiner(accumulator, element) | |
return accumulator | |
} | |
} | |
} | |
let nums = [0,1,2,3,4,5].scan(+) | |
print(nums) //[0, 1, 3, 6, 10, 15] | |
let chars = ["0","1","2","3","4","5"].scan(+) | |
print(chars) //["0", "01", "012", "0123", "01234", "012345"] | |
let range = (1..<5).scan(0, +) | |
print(range) //[0, 1, 3, 6, 10] | |
///Overload of Dictionar::updateValue that takes a function | |
extension Dictionary { | |
mutating func updateValue(_ updater: (Value) -> Value, forKey key: Key) -> Value? { | |
if let newValue = self[key] { | |
let value = updater(newValue) | |
return self.updateValue(value, forKey: key) | |
} | |
return nil | |
} | |
} | |
var hues = ["Heliotrope": 296, "Coral": 16, "Aquamarine": 156] | |
let update = 23 | |
if let oldValue = hues.updateValue( { _ in 3 * update }, forKey: "Coral") { | |
print("The old value of \(oldValue) was replaced with a new one.") | |
} | |
print(hues["Coral"] ?? "no value") | |
if let oldValue = hues.updateValue( { old in 3 * old }, forKey: "Aquamarine") { | |
print("The old value of \(oldValue) was replaced with a new one.") | |
} | |
print(hues["Aquamarine"] ?? "no value") | |
///Safely wait for EventLoopFuture to complete | |
extension EventLoopFuture { | |
func join<E>() -> E? where Value == E? { | |
let semaphore = DispatchSemaphore(value: 0) | |
var entity : E? = nil | |
DispatchQueue.global().async { | |
do { | |
entity = try self.wait() | |
semaphore.signal() | |
} catch { | |
print("\(error.localizedDescription)") | |
} | |
} | |
semaphore.wait() | |
return entity | |
} | |
func join<E>() -> [E] where Value == [E] { | |
let semaphore = DispatchSemaphore(value: 0) | |
var entities : [E] = [] | |
DispatchQueue.global().async { | |
do { | |
entities = try self.wait() | |
semaphore.signal() | |
} catch { | |
print("\(error.localizedDescription)") | |
} | |
} | |
semaphore.wait() | |
return entities | |
} | |
} | |
///Pipe Forward Operator | |
precedencegroup ForwardApplication { | |
associativity: left | |
} | |
infix operator |> : ForwardApplication | |
func |> <A, B>(x: A, function: (A) -> B) -> B { | |
return function(x) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment