Home > Net >  How to convert String to UTF-8 to Integer in Swift
How to convert String to UTF-8 to Integer in Swift

Time:07-19

I'm trying to take each character (individual number, letter, or symbol) from a string file name without the extension and put each one into an array index as an integer of the utf-8 code (i.e. if the file name is "A1" without the extension, I would want "A" as an int "41" in first index, and "1" as int "31" in second index)

Here is the code I have but I'm getting this error "No exact matches in call to instance method 'append'", my guess is because .utf8 still keeps it as a string type:

for i in allNoteFiles {
        var CharacterArray : [Int] = []
        
        for character in i {
            var utf8Character = String(character).utf8 
            CharacterArray.append(utf8Character)    //error is here
        }
....`//more code down here within the for in loop using CharacterArray indexes`

I'm sure the answer is probably simple, but I'm very new to Swift.

I've tried appending var number instead with:

var number = Int(utf8Character)

and

var number = (utf8Character).IntegerValue

but I get errors "No exact matches in call to initializer" and "Value of type 'String.UTF8View' has no member 'IntegerValue'"

Any help at all would be greatly appreciated. Thanks!

CodePudding user response:

The reason

var utf8Character = String(character).utf8 
CharacterArray.append(utf8Character) 

doesn't work for you is because utf8Character is not a single integer, but a UTF8View: a lightweight way to iterate over the UTF-8 codepoints in a string. Every Character in a String can be made up of any number of UTF-8 bytes (individual integers) — while ASCII characters like "A" and "1" map to a single UTF-8 byte, the vast majority of characters do not: every UTF-8 code point maps to between 1 and 4 individual bytes. The Encoding section of UTF-8 on Wikipedia has a few very illustrative examples of how this works.

Now, assuming that you do want to split a string into individual UTF-8 bytes (either because you can guarantee your original string is ASCII-only, so the assumption that "character = byte" holds, or because you actually care about the bytes [though this is rarely the case]), there's a short and idiomatic solution to what you're looking for.

String.UTF8View is a Sequence of UInt8 values (individual bytes), and as such, you can use the Array initializer which takes a Sequence:

let characterArray: [UInt8] = Array(i.utf8)

If you need an array of Int values instead of UInt8, you can map the individual bytes ahead of time:

let characterArray: [UInt8] = Array(i.utf8.lazy.map { Int($0) })

(The .lazy avoids creating and storing an array of values in the middle of the operation.)

However, do note that if you aren't careful (e.g., your original string is not ASCII), you're bound to get very unexpected results from this operation, so keep that in mind.

  • Related