The unicodeScalars.map and count are equal. But the index doesn't. Why aren't the indices equal? For unicodeScalars, the position should be the same, in my opinion.
source code
import Foundation
let ns:NSString = "A 🐵 makes 🙈🙉🙈🙉."
let s = ns as String
let s1 = s + ""
let monkeyFace:Character = "🙈"
let monkeyFaceScalar = UnicodeScalar(String(monkeyFace))!
if let i = s.unicodeScalars.firstIndex(of: monkeyFaceScalar),
let i1 = s1.unicodeScalars.firstIndex(of: monkeyFaceScalar) {
print(i == i1)
print(s.unicodeScalars[i])
print(s1.unicodeScalars[i1])
}
print(s.unicodeScalars.count == s1.unicodeScalars.count)
print(s.unicodeScalars.map({$0}) == s1.unicodeScalars.map{$0})
// prints true
Indices are not interchangeable between collections, except for a few exceptions like Array. If you want to compare positions between two different instances of a string, you’ll have to find the distance from startIndex and compare that. Comparing indices directly may not work since they can be implemented in term of pointers within the data structure.
It seems to be heavily implied by SE-0065 since you need the corresponding collection to mutate the index validly.
IIUC, for current implementation details, String.Index (which is shared among all its views) uses code points, which may differ among different encodings.
FWIW, I couldn't reproduce it on Swift 5.0.1 (Ubuntu 18.04). i == i1 returns true.