3

This comparison worked in Swift 2 but doesn't anymore in Swift 3:

let myStringContainsOnlyOneCharacter = mySting.rangeOfComposedCharacterSequence(at: myString.startIndex) == mySting.characters.indices

How do I compare Range and DefaultBidirectionalIndices?

Manuel
  • 14,274
  • 6
  • 57
  • 130
  • Have a look at http://stackoverflow.com/a/39104563/1187415, which contains a `isSingleComposedCharacter` definition for both Swift 2 and Swift 3. – Martin R Sep 16 '16 at 14:13

2 Answers2

5

From SE-0065 – A New Model for Collections and Indices

In Swift 2, collection.indices returned a Range<Index>, but because a range is a simple pair of indices and indices can no longer be advanced on their own, Range<Index> is no longer iterable.

In order to keep code like the above working, Collection has acquired an associated Indices type that is always iterable, ...

Since rangeOfComposedCharacterSequence returns a range of character indices, the solution is not to use indices, but startIndex..<endIndex:

myString.rangeOfComposedCharacterSequence(at: myString.startIndex) 
== myString.startIndex..<myString.endIndex
Community
  • 1
  • 1
Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
1

As far as I know, String nor String.CharacterView does not have a concise method returning Range<String.Index> or something comparable to it.

You may need to create a Range explicitly with range operator:

let myStringContainsOnlyOneCharacter = myString.rangeOfComposedCharacterSequence(at: myString.startIndex)
    == myString.startIndex..<myString.endIndex

Or compare only upper bound, in your case:

let onlyOne = myString.rangeOfComposedCharacterSequence(at: myString.startIndex).upperBound
    == myString.endIndex
OOPer
  • 47,149
  • 6
  • 107
  • 142
  • OOPs (again), did not see your answer ... – You might want to add the reference to SE-0065, then I can delete mine. – Martin R Sep 16 '16 at 14:43
  • @MartinR, your answer has a better reference. Please do not hesitate to post a better answer. – OOPer Sep 16 '16 at 14:48