Last active
May 14, 2020 15:42
-
-
Save CTMacUser/96b3d851ea08536a69e753c89a70b035 to your computer and use it in GitHub Desktop.
This file contains hidden or 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 { | |
/// If the collection does not have the given sequence as a prefix when | |
/// using the given predicate to compare elements, returns the collection | |
/// as-is; otherwise, returns the part of the collection after that prefix. | |
/// | |
/// The predicate must be an equivalence relation over the elements. | |
/// | |
/// Whether a prefix was actually dropped can be tested by checking if the | |
/// returned sub-sequence's `startIndex` is greater than the collection's | |
/// starting index. | |
/// | |
/// - Parameters: | |
/// - possiblePrefix: A sequence to compare to this collection. | |
/// - areEquivalent: A predicate that returns `true` if its two | |
/// arguments are equivalent; otherwise, `false`. | |
/// - Returns: Either `dropFirst(Array(possiblePrefix).count)` or `self`, | |
/// depending on `starts(with: possiblePrefix, by: areEquivalent)`. | |
/// | |
/// - Complexity: O(*n*), where *n* is the shorter of this collection and | |
/// `possiblePrefix`. | |
public func dropPrefix<S: Sequence>( | |
of possiblePrefix: S, | |
by areEquivalent: (Element, S.Element) throws -> Bool | |
) rethrows -> SubSequence { | |
let delta = try possiblePrefix.firstDelta(against: indices) { | |
try areEquivalent(self[$1], $0) | |
} | |
if delta.0 == nil { | |
return self[(delta.1 ?? endIndex)...] | |
} else { | |
return self[...] | |
} | |
} | |
} | |
extension Collection where Element: Equatable { | |
/// If the collection starts with the given sequence as a prefix, returns | |
/// the part of the collection after the prefix; otherwise, returns the | |
/// collection as-is. | |
/// | |
/// Whether a prefix was actually dropped can be tested by checking if the | |
/// returned sub-sequence's `startIndex` is greater than the collection's | |
/// starting index. | |
/// | |
/// - Parameters: | |
/// - possiblePrefix: A sequence to compare to this collection. | |
/// - Returns: Either `dropFirst(Array(possiblePrefix).count)` or `self`, | |
/// depending on `starts(with: possiblePrefix)`. | |
/// | |
/// - Complexity: O(*n*), where *n* is the shorter of this collection and | |
/// `possiblePrefix`. | |
@inlinable | |
public func dropPrefix<S: Sequence>(of possiblePrefix: S) -> SubSequence | |
where S.Element == Element { | |
return dropPrefix(of: possiblePrefix, by: ==) | |
} | |
} | |
extension BidirectionalCollection { | |
/// If this collection does not have the given collection as a suffix when | |
/// using the given predicate to compare elements, returns this collection | |
/// as-is; otherwise, returns the part of this collection before that | |
/// suffix. | |
/// | |
/// The predicate must be an equivalence relation over the elements. | |
/// | |
/// Whether a suffix was actually dropped can be tested by checking if the | |
/// returned sub-sequence's `endIndex` is less than this collection's | |
/// past-the-end index. | |
/// | |
/// - Parameters: | |
/// - possibleSuffix: A collection to compare to this collection. | |
/// - areEquivalent: A predicate that returns `true` if its two | |
/// arguments are equivalent; otherwise, `false`. | |
/// - Returns: Either `dropLast(Array(possibleSuffix).count)` or `self`, | |
/// depending on this collection's suffix. | |
/// | |
/// - Complexity: O(*n*), where *n* is the shorter of this collection and | |
/// `possibleSuffix`. | |
@inlinable | |
public func dropSuffix<C: BidirectionalCollection>( | |
of possibleSuffix: C, | |
by areEquivalent: (Element, C.Element) throws -> Bool | |
) rethrows -> SubSequence { | |
let result = try reversed().dropPrefix(of: possibleSuffix.reversed(), by: areEquivalent) | |
return self[result.endIndex.base ..< result.startIndex.base] | |
} | |
} | |
extension BidirectionalCollection where Element: Equatable { | |
/// If this collection starts with the given collection as a suffix, returns | |
/// the part of this collection before the suffix; otherwise, returns this | |
/// collection as-is. | |
/// | |
/// Whether a suffix was actually dropped can be tested by checking if the | |
/// returned sub-sequence's `endIndex` is less than this collection's | |
/// past-the-end index. | |
/// | |
/// - Parameters: | |
/// - possibleSuffix: A collection to compare to this collection. | |
/// - Returns: Either `dropFirst(Array(possibleSuffix).count)` or `self`, | |
/// depending on this collection's suffix. | |
/// | |
/// - Complexity: O(*n*), where *n* is the shorter of this collection and | |
/// `possibleSuffix`. | |
@inlinable | |
public func dropSuffix<C: BidirectionalCollection>(of possibleSuffix: C) | |
-> SubSequence where C.Element == Element { | |
return dropSuffix(of: possibleSuffix, by: ==) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment