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
let xs = [0,1,2,3,4,5] | |
let double: (Int) -> Int = { $0 * 2 } | |
let isEven: (Int) -> Bool = { $0 % 2 == 0 } | |
// Goal: [0,2,4,6,4,10]. Double all but the last even element. | |
extension Collection { | |
func mapExceptLast(matching predicate: (Element) -> Bool, transform: (Element) -> Element) -> [Element] { | |
var result: [Element] = [] |
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
/// Returns a binary predicate using the given key path to create an ascending order | |
/// for elements of type `Root`. | |
func ascending<Root, Value: Comparable>(_ path: KeyPath<Root, Value>) -> (Root, Root) -> Bool { | |
return { $0[keyPath: path] < $1[keyPath: path] } | |
} | |
/// Returns a binary predicate using the given key path to create a descending order | |
/// for elements of type `Root`. | |
func descending<Root, Value: Comparable>(_ path: KeyPath<Root, Value>) -> (Root, Root) -> Bool { | |
return { $0[keyPath: path] > $1[keyPath: path] } |
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
extension Sequence { | |
func interspersed(with element: Element) -> [Element] { | |
var result: [Element] = [] | |
var iterator = makeIterator() | |
if let first = iterator.next() { | |
result.append(first) | |
} | |
while let elementFromSelf = iterator.next() { | |
result.append(element) | |
result.append(elementFromSelf) |
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
extension BidirectionalCollection { | |
func drop(first: Int, last: Int) -> SubSequence { | |
return self.dropFirst(first).dropLast(last) | |
} | |
} | |
let numbers = 0..<10 | |
numbers.drop(first: 1, last: 1) // 1..<9 | |
numbers.drop(first: 2, last: 4) // 2..<6 |
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
extension Collection { | |
/// Chooses at random the given number of elements, using reservoir sampling | |
/// aka Algorithm R. | |
/// | |
/// - Complexity: O(*n*) where *n* is the collection's count. | |
func choose<T>(upTo max: Int, using generator: T) -> [Element] | |
where T: RandomNumberGenerator | |
{ | |
var i = index(startIndex, offsetBy: max, limitedBy: endIndex) ?? endIndex | |
var result = self[..<i].shuffled(using: generator) |
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
/// This is a useful index that can store a comparable element or the end of | |
/// a collection. Similar to https://github.com/apple/swift/pull/15193 | |
enum IndexWithEnd<T : Comparable> : Comparable { | |
case element(T) | |
case end | |
static func < (lhs: IndexWithEnd, rhs: IndexWithEnd) -> Bool { | |
switch (lhs, rhs) { | |
case (.element(let l), .element(let r)): | |
return l < r |
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
extension Sequence { | |
func last(where predicate: (Element) throws -> Bool) rethrows -> Element? { | |
var result: Element? = nil | |
for el in self { | |
if try predicate(el) { | |
result = el | |
} | |
} | |
return result | |
} |
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
// Speculation in regards to https://forums.swift.org/t/shorthand-for-offsetting-startindex-and-endindex/9397/133 | |
/// A pair of offsets that can be used to slice a collection. | |
/// | |
/// In order to have `RangeExpression` conformance, this would need | |
/// a phantom `Bound` type, which would unnecessarily restrict its | |
/// usage. In addition, the `RangeExpression.contains(_:)` method | |
/// couldn't be implemented without access to a collection with the | |
/// actual indices to resolve. | |
struct Offsets { |
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
public struct PeekingIterator<T : IteratorProtocol> : IteratorProtocol { | |
fileprivate var _iterator: T | |
public fileprivate(set) var buffered: T.Element? | |
public init(_ iterator: T) { | |
self._iterator = iterator | |
self.buffered = _iterator.next() | |
} | |
public init<U: Sequence>(_ sequence: U) where U.Iterator == T { |
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
/// Performs an exponential search to find the number of steps from `start` to `end` | |
/// without using division. | |
func count<T: Numeric & Comparable>(from start: T, to end: T, by step: T) -> Int { | |
var count = 1 | |
var current = start | |
var stepMultipliers = [1] | |
while current < end { | |
count += stepMultipliers.last! | |
current += step * T(exactly: stepMultipliers.last!)! | |
stepMultipliers.append(stepMultipliers.last! * 2) |