Skip to content

Instantly share code, notes, and snippets.

@zackdotcomputer
Last active September 7, 2020 21:46
Show Gist options
  • Save zackdotcomputer/9d83f4d48af7127cd0bea427b4d6d61b to your computer and use it in GitHub Desktop.
Save zackdotcomputer/9d83f4d48af7127cd0bea427b4d6d61b to your computer and use it in GitHub Desktop.
Range<Int> substring finder for Swift Strings - Unsafe but Simple
//
// String+CountableRange.swift
//
// Created by Zack Sheppard on 8/30/20.
// Copyright © 2020 Zack Sheppard. All rights reserved.
// Available under the MIT License
//
import Foundation
/// This extension is available at
/// https://gist.github.com/zackdotcomputer/9d83f4d48af7127cd0bea427b4d6d61b
extension StringProtocol {
/// Access the range of the search string as integer indices
/// in the rendered string.
/// - NOTE: This is "unsafe" because it may not return what you expect if
/// your string contains single symbols formed from multiple scalars.
/// - Returns: A `Range<Int>` that will align with the Swift String.Index
/// from the result of the standard function range(of:).
func countableRange<SearchType: StringProtocol>(
of search: SearchType,
options: String.CompareOptions = [],
range: Range<String.Index>? = nil,
locale: Locale? = nil
) -> CountableRange<Int>? {
guard let trueRange = self.range(of: search, options: options, range: range, locale: locale) else {
return nil
}
let intStart = self.distance(from: startIndex, to: trueRange.lowerBound)
let intEnd = self.distance(from: trueRange.lowerBound, to: trueRange.upperBound) + intStart
return Range(uncheckedBounds: (lower: intStart, upper: intEnd))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment