Skip to content

Instantly share code, notes, and snippets.

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] = []
/// 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] }
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)
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
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 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
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
}
// 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 {
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 {
/// 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)