14

I have an array of unicode scalars (Type is [UnicodeScalar])

like:

let array = [UnicodeScalar("f")!, UnicodeScalar("o")!, UnicodeScalar("o")!]

or

let array2 = "bar".unicodeScalars

how can I convert efficiently these arrays into a strings again?

Expect:

let string1 = ?? // "foo"
let string2 = ?? // "bar"
1

4 Answers 4

19

The second case is simpler because array2 is a UnicodeScalarView and not an array:

let array2 = "bar".unicodeScalars

let str2 = String(array2)
print(str2) // bar

If you have an array (or any sequence) of Unicode scalars then you can start with an empty string and append the elements to its unicodeScalars view:

let array = [UnicodeScalar("f")!, UnicodeScalar("o")!, UnicodeScalar("o")!]
// Or: let array: [UnicodeScalar] = ["f", "o", "o"]

var str1 = ""
str1.unicodeScalars.append(contentsOf: array)
print(str1) // foo

Of course you can define a custom extension for that purpose:

extension String {
    init<S: Sequence>(unicodeScalars ucs: S)
        where S.Iterator.Element == UnicodeScalar
    {
        var s = ""
        s.unicodeScalars.append(contentsOf: ucs)
        self = s
    }
}

let str1 = String(unicodeScalars: array)
Sign up to request clarification or add additional context in comments.

7 Comments

@LeoDabus: You are right, that is far simpler. You should add an answer ... (with or without extension :)
I learned that with @dfri so adding it as my answer it is not fair.
@LeoDabus: I do not see the problem. You have a good solution for this question which should not be hidden in the comments. You can add a reference for proper attribution.
ok I have posted the comment as an answer with proper attribution
@dfri: Or (for a literal array): let array: [UnicodeScalar] = ["f", "o", "o"]
|
7

You can use this extension from @dfri to initialize a string from a UnicodeScalar sequence as follow:

extension Sequence where Element == UnicodeScalar { 
    var string: String { .init(String.UnicodeScalarView(self)) } 
}

let array: [UnicodeScalar] = ["f", "o", "o"]
print(array.string) //  "foo\n"

Comments

1

Another way to convert [UnicodeScalar] to String:

let array = [UnicodeScalar("f")!, UnicodeScalar("o")!, UnicodeScalar("o")!]
let string1 = String(array.map{Character($0)})
print(string1 == "foo") //->true

3 Comments

Doesn't this break for characters composed of multiple unicode scalarS?
@Alexander: No, doesn't. They are combined again when creating the string.
@MartinR Interesting, I didn't know that
1

With Swift 5, you can use one of the following ways in order to get a string from a collection of Unicode scalars.


#1. Using String's init(_:) initializer

String has an init(_:) initializer with the following declaration:

init(_ unicodeScalars: String.UnicodeScalarView)

Creates a string corresponding to the given collection of Unicode scalars.

The Playground sample code below shows how to use init(_:) in order to get a String instance from a String.UnicodeScalarView instance:

let string = "foo"
let unicodeScalarView = string.unicodeScalars

let newString = String(unicodeScalarView)
print(newString) // prints: foo

If you initially have an array of Unicode scalars, you can convert it first to a String.UnicodeScalarView instance using String.UnicodeScalarView's init(_:) initializer:

let scalarsArray = [Unicode.Scalar("f"), Unicode.Scalar("o"), Unicode.Scalar("o")]

let unicodeScalarView = String.UnicodeScalarView(scalarsArray)
let newString = String(unicodeScalarView)
print(newString) // prints: foo

#2. Using String's init(_:) initializer

String has an init(_:) initializer with the following declaration:

init(_ scalar: Unicode.Scalar)

The following Playground sample codes show how to iterate over an array of Unicode scalars using String's init(_:) in order to create a new string:

let scalarsArray = [Unicode.Scalar("f"), Unicode.Scalar("o"), Unicode.Scalar("o")]

let string = scalarsArray.reduce("", { partialResult, scalar in
    return partialResult + String(scalar)
})
print(string) // prints: foo
let scalarsArray = [Unicode.Scalar("f"), Unicode.Scalar("o"), Unicode.Scalar("o")]

let newString = scalarsArray.map(String.init).joined()
print(newString) // prints: foo

#3. Using String.UnicodeScalarView's append(contentsOf:) method

If you have an existing string and want to append the elements of a Unicode scalars array into it, you can use append(contentsOf:):

let scalarsArray = [Unicode.Scalar("f"), Unicode.Scalar("o"), Unicode.Scalar("o")]

var newString = ""
newString.unicodeScalars.append(contentsOf: scalarsArray)
print(newString) // prints: foo

#4. Using Character's init(_:) initializer

Another approach would consist of iterating over a collection of Unicode scalars, convert them into characters (using Character's init(_:) initializer) then create a new string from those characters:

let scalarsArray = [Unicode.Scalar("f"), Unicode.Scalar("o"), Unicode.Scalar("o")]

let charactersArray = scalarsArray.map(Character.init)
let newString = String(charactersArray)
print(newString) // prints: foo

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.