How to find the previous or next character?

Given a character (e.g. :vulcan_salute:), how do I find the character that's immediately greater or lesser than it?

There is a finite number of Unicode characters, and Character conforms to Comparable. So there must be a character that immediately precedes or succeeds :vulcan_salute:, and a way to find it. However, I am not able find much information about it in Character's source, in which character comparison is just delegated to string comparison:

extension Character: Comparable {
  @inlinable @inline(__always)
  @_effects(readonly)
  public static func < (lhs: Character, rhs: Character) -> Bool {
    return lhs._str < rhs._str
  }
}

There is an infinite number of possible Character instances (extended grapheme clusters in Unicode parlance). a + (β—ŒΜ Γ— ∞) is still a single Character. That means there is no such thing as β€œthe character before b”.

There is a finite number of Unicode scalars (Unicode.Scalar, element of String.UnicodeScalarView, accessible through myString.unicodeScalars). If that is what you want to use, you can take the UInt32 value of a scalar and then keep incrementing it until backwards initialization from the integer value succeeds. But that strategy won’t match any meaningful sort order expected by humans; the order they were encoded is (mostly) just a fluke of history. The strategy also won’t match the behaviour of String’s Comparable conformance, since Γ‘ and a + β—ŒΜ are different scalar sequences but still equal strings.

8 Likes

Thanks! I forgot that you can use combining characters recursively. I guess the premise to my question is invalid then.

1 Like