swift-algorithms icon indicating copy to clipboard operation
swift-algorithms copied to clipboard

Add `replaceOccurrences(of:with:)`

Open timvermeulen opened this issue 4 years ago • 0 comments

Depends on #155.

Replace occurrences of a given subsequence with a given replacement.

  • replacingOccurrences(of:with:)
  • lazy.replacingOccurrences(of:with:)
  • replaceOccurrences(of:with:)

The lazy overloads are available on all lazy collections while the eager ones are only available on range-replaceable collections, which is a little odd.

extension RangeReplaceableCollection {
  public func replacingOccurrences<Target: Collection, Replacement: Collection>(
    of target: Target,
    with replacement: Replacement,
    subrange: Range<Index>,
    maxReplacements: Int = .max,
    by areEquivalent: (Element, Target.Element) throws -> Bool
  ) rethrows -> Self where Replacement.Element == Element
  
  public func replacingOccurrences<Target: Collection, Replacement: Collection>(
    of target: Target,
    with replacement: Replacement,
    maxReplacements: Int = .max,
    by areEquivalent: (Element, Target.Element) throws -> Bool
  ) rethrows -> Self where Replacement.Element == Element
}

extension RangeReplaceableCollection where Element: Equatable {
  public func replacingOccurrences<Target: Collection, Replacement: Collection>(
    of target: Target,
    with replacement: Replacement,
    subrange: Range<Index>,
    maxReplacements: Int = .max
  ) -> Self where Target.Element == Element, Replacement.Element == Element
  
  public func replacingOccurrences<Target: Collection, Replacement: Collection>(
    of target: Target,
    with replacement: Replacement,
    maxReplacements: Int = .max
  ) -> Self where Target.Element == Element, Replacement.Element == Element
}

extension LazyCollectionProtocol {
  public func replacingOccurrences<Target: Collection, Replacement: Collection>(
    of target: Target,
    with replacement: Replacement,
    subrange: Range<Elements.Index>,
    maxReplacements: Int = .max,
    by areEquivalent: @escaping (Element, Target.Element) -> Bool
  ) -> LazyCollection<
    Chain2<
      Elements.SubSequence,
      Chain2<
        JoinedByCollection<
          SplitCollection<Elements.SubSequence, Target>,
          Replacement
        >,
        Elements.SubSequence
      >
    >
  > where Replacement.Element == Element
  
  public func replacingOccurrences<Target: Collection, Replacement: Collection>(
    of target: Target,
    with replacement: Replacement,
    maxReplacements: Int = .max,
    by areEquivalent: @escaping (Element, Target.Element) -> Bool
  ) -> JoinedByCollection<
         LazyCollection<SplitCollection<Elements, Target>>, Replacement>
    where Replacement.Element == Element
}

extension LazyCollectionProtocol where Element: Equatable {
  public func replacingOccurrences<Target: Collection, Replacement: Collection>(
    of target: Target,
    with replacement: Replacement,
    subrange: Range<Elements.Index>,
    maxReplacements: Int = .max
  ) -> LazyCollection<
    Chain2<
      Elements.SubSequence,
      Chain2<
        JoinedByCollection<
          SplitCollection<Elements.SubSequence, Target>,
          Replacement
        >,
        Elements.SubSequence
      >
    >
  > where Target.Element == Element, Replacement.Element == Element
  
  public func replacingOccurrences<Target: Collection, Replacement: Collection>(
    of target: Target,
    with replacement: Replacement,
    maxReplacements: Int = .max
  ) -> JoinedByCollection<
         LazyCollection<SplitCollection<Elements, Target>>, Replacement>
    where Target.Element == Element, Replacement.Element == Element
}

extension RangeReplaceableCollection {
  public mutating func replaceOccurrences<
    Target: Collection,
    Replacement: Collection
  >(
    of target: Target,
    with replacement: Replacement,
    maxReplacements: Int = .max,
    by areEquivalent: (Element, Target.Element) throws -> Bool
  ) rethrows where Replacement.Element == Element
}

extension RangeReplaceableCollection where Element: Equatable {
  public mutating func replaceOccurrences<
    Target: Collection,
    Replacement: Collection
  >(
    of target: Target,
    with replacement: Replacement,
    maxReplacements: Int = .max
  ) where Target.Element == Element, Replacement.Element == Element
}

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

timvermeulen avatar Jul 23 '21 15:07 timvermeulen