chakrit
chakrit

Reputation: 61518

How to compare Swift String.Index?

So I have an instance of Range<String.Index> obtained from a search method. And also a standalone String.Index by other means how can I tell wether this index is within the aforementioned range or not?

Example code:

let str = "Hello!"

let range = Range(start: str.startIndex, end: str.endIndex)
let anIndex = advance(str.startIndex, 3)

// How to tell if `anIndex` is within `range` ?

Since comparison operators do not work on String.Index instances, the only way seems to be to perform a loop through the string using advance but this seems overkill for such a simple operation.

Upvotes: 4

Views: 4588

Answers (1)

jtbandes
jtbandes

Reputation: 118691

The beta 5 release notes mention:

The idea of a Range has been split into three separate concepts:

  • Ranges, which are Collections of consecutive discrete ForwardIndexType values. Ranges are used for slicing and iteration.
  • Intervals over Comparable values, which can efficiently check for containment. Intervals are used for pattern matching in switch statements and by the ~= operator.
  • Striding over Strideable values, which are Comparable and can be advanced an arbitrary distance in O(1).

Efficient containment checking is what you want, and this is possible since String.Index is Comparable:

let range = str.startIndex..<str.endIndex as HalfOpenInterval
// or this:
let range = HalfOpenInterval(str.startIndex, str.endIndex)

let anIndex = advance(str.startIndex, 3)

range.contains(anIndex) // true
// or this:
range ~= anIndex // true

(For now, it seems that explicitly naming HalfOpenInterval is necessary, otherwise the ..< operator creates a Range by default, and Range doesn't support contains and ~= because it uses only ForwardIndexType.)

Upvotes: 6

Related Questions