37

The output of the [Character] Array currently is:

["E", "x", "a", "m", "p", "l", "e"]

It should be:

Example

It could be that " is in the array, like this: """. That output should be ".

Thank you!

1
  • 2
    You'll get much better answers if you show the declaration and definition of your array. Commented Nov 14, 2016 at 23:11

3 Answers 3

78

The other answer(s) cover the case where your array is one of String elements (which is most likely the case here: since you haven't supplied us the type of the array, we could use Swift own type inference rules to speculatively infer the type to be [String]).

In case the elements of your array are in fact of type Character, however, you could use the Character sequence initializer of String directly:

let charArr: [Character] = ["E", "x", "a", "m", "p", "l", "e"]
let str = String(charArr) // Example

W.r.t. your comment below: if your example array is, for some reason, one of Any elements (which is generally not a good idea to use explicitly, but sometimes the case when recieving data from some external source), you first need to perform an attempted conversion of each Any element to String type, prior to concenating the converted elements to a single String instance. After the conversion, you will be working with an array of String elements, in which case the methods shown in the other answers will be the appropriate method of concenation:

// e.g. using joined()
let arr: [Any] = ["E", "x", "a", "m", "p", "l", "e"]
let str = arr.flatMap { $0 as? String }.joined()
print(str) // example

You could naturally also (attempt to) convert from Any to Character elements, but even in this case you would have to go via String instances, which means that for the [Any] case, the joined() alternative above is to prefer over the one below:

let arr: [Any] = ["E", "x", "a", "m", "p", "l", "e"]
let str = String(arr.flatMap { ($0 as? String)?.characters.first })
print(str) // example
Sign up to request clarification or add additional context in comments.

4 Comments

I forgot to mention indeed that the array type is [Character]. When I try your solution, I get this error in red: " 'init' has been renamed to 'init(describing:)'" :(
@Petravd1994: Could it be that you have an optional array?
I changed it to let str = String(describing: charr) however the output is exactly the same as the array... it is really frustrating now. I made this array: var Array1: [Any] = [] and than appended elements by using Array1.append(Array2[0]). Now I want it that Array1 is converted to a string without the "" and ",". The array is not optional
String(describing:) produces a string with essentially the same output as print(). Why are you creating the array as an [Any]? Swift has no idea that it's an [Character], so it doesn't allow you to call the proper initilizer with it.
11

Just use joined() with default "" separator:

let joinedString = ["E", "x", "a", "m", "p", "l", "e"].joined()

1 Comment

It would be worthwhile to see how this compares in performance to the String initializer. I suspect that will be faster, because it could skip on the memory reallocation
5
let e = ["E", "x", "a", "m", "p", "l", "e"]
print(e.reduce ("", +))

7 Comments

That implementation isn't performant (it can require a log_2(count) number of memory reallocations. It also isn't necessary, because String has an initializer that constructs a string from a Character array.
You should probably just joined() method, but nevertheless the apple documentation does claim "Behind the scenes, Swift’s compiler optimizes string usage so that actual copying takes place only when absolutely necessary. This means you always get great performance when working with strings as value types." I suppose I should look at the disassembly and see what it actually emits. developer.apple.com/library/content/documentation/Swift/…
I would appreciate taking a look at your findings. The issue here is not the copying that occurs due to value semantics, but the reallocation that's necessary when appending to a string whose length is about to exceed its allocated capacity.
@AlexanderMomchliov note that String instances in Swift use an exponential growth strategy to (re-)allocate its contiguous storage, with the effect that appending characters to a String instance will be a constant time operation when amortized(/avaraged) over many invocations. Reallocation should not be an issue in the example above (reduce being slower than e.g. classic loops in some contexts is another matter). See e.g. the comment section Performance Optimizations in swift/stdlib/public/core/String.swift.
So I didn't have much luck with either the SIL or the Assembly so I decided to just profile the methods instead. I created 100,000 5-8 character random strings and measured the average time to .join them at 0.066 seconds and to .reduce them at 0.039 seconds. It turns out reduce is much faster. Maybe the compiler is eliminating the function call and putting in reduce as a loop?
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.