Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

First Mismatching Elements, or Indexes Thereof #37

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

CTMacUser
Copy link
Contributor

Description

This request adapts the C++ function mismatch, having methods returning the first mismatching elements between two sequences. There are variant methods returning the corresponding indexes instead, i.e. the past-the-end points for a common prefix. Finally, another set of methods reverses the search to find a common suffix for bidirectional collections.

Detailed Design

extension Sequence {
    /// Returns the first non-matching element pair found when comparing this
    /// sequence to the given sequence element-wise, using the given predicate as
    /// the equivalence test.
    func firstDelta<PossibleMirror>(against possibleMirror: PossibleMirror, by areEquivalent: (Element, PossibleMirror.Element) throws -> Bool) rethrows -> (Element?, PossibleMirror.Element?) where PossibleMirror : Sequence
}

extension Sequence where Self.Element : Equatable {
    /// Returns the first non-equal element pair found when comparing this
    /// sequence to the given sequence element-wise.
    func firstDelta<PossibleMirror>(against possibleMirror: PossibleMirror) -> (Element?, Element?) where PossibleMirror : Sequence, Self.Element == PossibleMirror.Element
}

extension Collection {
    /// Finds the longest common prefix between this collection and the given
    /// collection, using the given predicate as the equivalence test, returning
    /// the past-the-end indexes of the respective subsequences.
    func diverges<PossibleMirror>(from possibleMirror: PossibleMirror, by areEquivalent: (Element, PossibleMirror.Element) throws -> Bool) rethrows -> (Index, PossibleMirror.Index) where PossibleMirror : Collection
}

extension Collection where Self.Element : Equatable {
    /// Finds the longest common prefix between this collection and the given
    /// collection, returning the past-the-end indexes of the respective
    /// subsequences.
    func diverges<PossibleMirror>(from possibleMirror: PossibleMirror) -> (Index, PossibleMirror.Index) where PossibleMirror : Collection, Self.Element == PossibleMirror.Element
}

extension BidirectionalCollection {
    /// Finds the longest common suffix between this collection and the given
    /// collection, using the given predicate as the equivalence test, returning
    /// the starting indexes of the respective subsequences.
    func converges<PossibleMirror>(with possibleMirror: PossibleMirror, by areEquivalent: (Element, PossibleMirror.Element) throws -> Bool) rethrows -> (Index, PossibleMirror.Index) where PossibleMirror : BidirectionalCollection
}

extension BidirectionalCollection where Self.Element : Equatable {
    /// Finds the longest common suffix between this collection and the given
    /// collection, returning the starting indexes of the respective subsequences.
    func converges<PossibleMirror>(with possibleMirror: PossibleMirror) -> (Index, PossibleMirror.Index) where PossibleMirror : BidirectionalCollection, Self.Element == PossibleMirror.Element
}
let a = [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32],
      b = [2, 4, 8, 16, 32]
a.firstDelta(against: b)  // returns (6, 8)
a.diverges(from: b)         // returns (2, 2)
a.converges(with: b)      // returns (15, 4)

Documentation Plan

The methods have block comments, and there is a guide file.

Test Plan

There is a test file included.

Source Impact

This request adds new API.

Checklist

  • I've added at least one test that validates that my change is working, if appropriate
  • I've followed the code style of the rest of the project
  • I've read the Contribution Guidelines
  • I've updated the documentation if necessary

Add a method to sequences that takes another sequence and an equivalence predicate to return the corresponding elements of where the sequences initially don't match.  If at least one sequence runs out before a mismatch, its corresponding return value is NIL.  Add an overload that defaults comparison to the standard equality operator.
Add a method to collections that takes another collection and an equivalence predicate to return the indexes for the corresponding elements of where the collections initially don't match. If at least one collection runs out before a mismatch, its corresponding return value is its source's past-the-end index. Add an overload that defaults comparison to the standard equality operator.
Add a method to bidirectional collections that takes another bidirectional collection and an equivalence predicate to return the indexes for the corresponding elements of where the collections permanently start matching. If at least one collection runs out before a backwards-searching mismatch, its corresponding return value is its source's starting index. Add an overload that defaults comparison to the standard equality operator.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant