I need a function to replace numbers 0..9 with characters A..J consecutively. How can I write it in Swift 3? Swift 3 string manipulation is so weird :| I tried accessing characters and then adding and offset (shifting) characters, but have no success.
1 Answer
Here is a possible solution to your problem which is also Unicode safe:
let string = "0123456789 abc xyz 9876543210"
// upper case A...J use 65; lower case a...j use 97
let shift = 65
let convertedString = String(string.characters.lazy.map{ char in
Int(String(char)).map{ Character(UnicodeScalar($0 + shift)!) } ?? char
})
Explanation
Idea/Problem
Map each character of the string to another (or same) character: 0...9 -> A...J, everything else stays
Implementation
Use a lazy character collection for performance reasons for large strings. A non lazy one would create an intermediate Array.
The mapping from one to another character goes through the following process:
Try to convert the character to an
Int(HereInt?)1.1 If it fails (is
nil) the nil coalescing operator (??) comes in to play and the input character is returnedThe Int value (
$0) now gets converted back to a Character through its (shifted) ASCII representation
Convert the lazily mapped collection to a
String. Swifts declaration of the initialiser:public init<S : Sequence>(_ characters: S) where S.Iterator.Element == Character { ... }
2 Comments
lazy? What is the advantage to that?lazy we would create an intermediate array of characters which requires a huge amount of memory if the string was long in the first place. See above under Implementation for the full explanation.