Get nth character of a string in Swift programming language

372,585

Solution 1

Attention: Please see Leo Dabus' answer for a proper implementation for Swift 4 and Swift 5.

Swift 4 or later

The Substring type was introduced in Swift 4 to make substrings faster and more efficient by sharing storage with the original string, so that's what the subscript functions should return.

Try it out here

extension StringProtocol {
    subscript(offset: Int) -> Character { self[index(startIndex, offsetBy: offset)] }
    subscript(range: Range<Int>) -> SubSequence {
        let startIndex = index(self.startIndex, offsetBy: range.lowerBound)
        return self[startIndex..<index(startIndex, offsetBy: range.count)]
    }
    subscript(range: ClosedRange<Int>) -> SubSequence {
        let startIndex = index(self.startIndex, offsetBy: range.lowerBound)
        return self[startIndex..<index(startIndex, offsetBy: range.count)]
    }
    subscript(range: PartialRangeFrom<Int>) -> SubSequence { self[index(startIndex, offsetBy: range.lowerBound)...] }
    subscript(range: PartialRangeThrough<Int>) -> SubSequence { self[...index(startIndex, offsetBy: range.upperBound)] }
    subscript(range: PartialRangeUpTo<Int>) -> SubSequence { self[..<index(startIndex, offsetBy: range.upperBound)] }
}

To convert the Substring into a String, you can simply do String(string[0..2]), but you should only do that if you plan to keep the substring around. Otherwise, it's more efficient to keep it a Substring.

It would be great if someone could figure out a good way to merge these two extensions into one. I tried extending StringProtocol without success, because the index method does not exist there. Note: This answer has been already edited, it is properly implemented and now works for substrings as well. Just make sure to use a valid range to avoid crashing when subscripting your StringProtocol type. For subscripting with a range that won't crash with out of range values you can use this implementation


Why is this not built-in?

The error message says "see the documentation comment for discussion". Apple provides the following explanation in the file UnavailableStringAPIs.swift:

Subscripting strings with integers is not available.

The concept of "the ith character in a string" has different interpretations in different libraries and system components. The correct interpretation should be selected according to the use case and the APIs involved, so String cannot be subscripted with an integer.

Swift provides several different ways to access the character data stored inside strings.

  • String.utf8 is a collection of UTF-8 code units in the string. Use this API when converting the string to UTF-8. Most POSIX APIs process strings in terms of UTF-8 code units.

  • String.utf16 is a collection of UTF-16 code units in string. Most Cocoa and Cocoa touch APIs process strings in terms of UTF-16 code units. For example, instances of NSRange used with NSAttributedString and NSRegularExpression store substring offsets and lengths in terms of UTF-16 code units.

  • String.unicodeScalars is a collection of Unicode scalars. Use this API when you are performing low-level manipulation of character data.

  • String.characters is a collection of extended grapheme clusters, which are an approximation of user-perceived characters.

Note that when processing strings that contain human-readable text, character-by-character processing should be avoided to the largest extent possible. Use high-level locale-sensitive Unicode algorithms instead, for example, String.localizedStandardCompare(), String.localizedLowercaseString, String.localizedStandardRangeOfString() etc.

Solution 2

Swift 5.2

let str = "abcdef"
str[1 ..< 3] // returns "bc"
str[5] // returns "f"
str[80] // returns ""
str.substring(fromIndex: 3) // returns "def"
str.substring(toIndex: str.length - 2) // returns "abcd"

You will need to add this String extension to your project (it's fully tested):

extension String {

    var length: Int {
        return count
    }

    subscript (i: Int) -> String {
        return self[i ..< i + 1]
    }

    func substring(fromIndex: Int) -> String {
        return self[min(fromIndex, length) ..< length]
    }

    func substring(toIndex: Int) -> String {
        return self[0 ..< max(0, toIndex)]
    }

    subscript (r: Range<Int>) -> String {
        let range = Range(uncheckedBounds: (lower: max(0, min(length, r.lowerBound)),
                                            upper: min(length, max(0, r.upperBound))))
        let start = index(startIndex, offsetBy: range.lowerBound)
        let end = index(start, offsetBy: range.upperBound - range.lowerBound)
        return String(self[start ..< end])
    }
}

Even though Swift always had out of the box solution to this problem (without String extension, which I provided below), I still would strongly recommend using the extension. Why? Because it saved me tens of hours of painful migration from early versions of Swift, where String's syntax was changing almost every release, but all I needed to do was to update the extension's implementation as opposed to refactoring the entire project. Make your choice.

let str = "Hello, world!"
let index = str.index(str.startIndex, offsetBy: 4)
str[index] // returns Character 'o'

let endIndex = str.index(str.endIndex, offsetBy:-2)
str[index ..< endIndex] // returns String "o, worl"

String(str.suffix(from: index)) // returns String "o, world!"
String(str.prefix(upTo: index)) // returns String "Hell"

Solution 3

I just came up with this neat workaround

var firstChar = Array(string)[0]

Solution 4

Xcode 11 • Swift 5.1

You can extend StringProtocol to make the subscript available also to the substrings:

extension StringProtocol {
    subscript(_ offset: Int)                     -> Element     { self[index(startIndex, offsetBy: offset)] }
    subscript(_ range: Range<Int>)               -> SubSequence { prefix(range.lowerBound+range.count).suffix(range.count) }
    subscript(_ range: ClosedRange<Int>)         -> SubSequence { prefix(range.lowerBound+range.count).suffix(range.count) }
    subscript(_ range: PartialRangeThrough<Int>) -> SubSequence { prefix(range.upperBound.advanced(by: 1)) }
    subscript(_ range: PartialRangeUpTo<Int>)    -> SubSequence { prefix(range.upperBound) }
    subscript(_ range: PartialRangeFrom<Int>)    -> SubSequence { suffix(Swift.max(0, count-range.lowerBound)) }
}

extension LosslessStringConvertible {
    var string: String { .init(self) }
}

extension BidirectionalCollection {
    subscript(safe offset: Int) -> Element? {
        guard !isEmpty, let i = index(startIndex, offsetBy: offset, limitedBy: index(before: endIndex)) else { return nil }
        return self[i]
    }
}

Testing

let test = "Hello USA 🇺🇸!!! Hello Brazil 🇧🇷!!!"
test[safe: 10]   // "🇺🇸"
test[11]   // "!"
test[10...]   // "🇺🇸!!! Hello Brazil 🇧🇷!!!"
test[10..<12]   // "🇺🇸!"
test[10...12]   // "🇺🇸!!"
test[...10]   // "Hello USA 🇺🇸"
test[..<10]   // "Hello USA "
test.first   // "H"
test.last    // "!"

// Subscripting the Substring
 test[...][...3]  // "Hell"

// Note that they all return a Substring of the original String.
// To create a new String from a substring
test[10...].string  // "🇺🇸!!! Hello Brazil 🇧🇷!!!"

Solution 5

No indexing using integers, only using String.Index. Mostly with linear complexity. You can also create ranges from String.Index and get substrings using them.

Swift 3.0

let firstChar = someString[someString.startIndex]
let lastChar = someString[someString.index(before: someString.endIndex)]
let charAtIndex = someString[someString.index(someString.startIndex, offsetBy: 10)]

let range = someString.startIndex..<someString.index(someString.startIndex, offsetBy: 10)
let substring = someString[range]

Swift 2.x

let firstChar = someString[someString.startIndex]
let lastChar = someString[someString.endIndex.predecessor()]
let charAtIndex = someString[someString.startIndex.advanceBy(10)]

let range = someString.startIndex..<someString.startIndex.advanceBy(10)
let subtring = someString[range]

Note that you can't ever use an index (or range) created from one string to another string

let index10 = someString.startIndex.advanceBy(10)

//will compile
//sometimes it will work but sometimes it will crash or result in undefined behaviour
let charFromAnotherString = anotherString[index10]
Share:
372,585
Mohsen
Author by

Mohsen

Follow me @mohsen____ Personal Website: azimi.me

Updated on November 29, 2021

Comments

  • Mohsen
    Mohsen over 2 years

    How can I get the nth character of a string? I tried bracket([]) accessor with no luck.

    var string = "Hello, world!"
    
    var firstChar = string[0] // Throws error
    

    ERROR: 'subscript' is unavailable: cannot subscript String with an Int, see the documentation comment for discussion

  • Doobeh
    Doobeh almost 10 years
    You can already loop through strings: for letter in "foo" { println(letter) }
  • drewag
    drewag almost 10 years
    @Doobeh I meant loop through and return the actual character like in my edit above
  • Doobeh
    Doobeh almost 10 years
    nice! It's funny how you can iterate through it, but not via an index. Swift's feeling pythonic but with harder edges.
  • markhunte
    markhunte almost 10 years
    I found using the myString.bridgeToObjectiveC().characterAtIndex(0) or (string as NSString ).characterAtIndex(0) returns an Int value of the character
  • drewag
    drewag almost 10 years
    @markhunte That's a good point. Another argument in my mind to use the native method
  • Nate Cook
    Nate Cook almost 10 years
    Don't use NSString methods for accessing individual characters from a Swift-native String - the two use different counting mechanisms, so you'll get unpredictable results with higher Unicode characters. The first method should be safe (once Swift's Unicode bugs are handled).
  • drewag
    drewag almost 10 years
    @NateCook you're right. I deleted the second option
  • masakielastic
    masakielastic almost 10 years
    How about "for (cur, char) in enumerate(self) {}"?
  • Martin R
    Martin R over 9 years
    Isn't that the same as var charAtIndex = string[advance(string.startIndex, 10)] in Sulthan's answer?
  • Jeff Hay
    Jeff Hay over 9 years
    This is a good quick work-around for the (common) case where you know you have UTF8 or ASCII encoded strings. Just be sure that the strings will never be in an encoding that uses more than one byte.
  • zaph
    zaph over 9 years
    String indexs are unique to a string. This is because different strings may have different multi-unit UTF-16 Characters and/or at different positions so the UTF-16 unit indexs will not match, may fall beyond the end or point inside a multi-unit UTF-16 Character.
  • Sulthan
    Sulthan over 9 years
    @Zaph That's obvious.
  • zaph
    zaph over 9 years
    Explaning why you say: "sometimes it will crash or result in undefined behaviour". Perhaps better to say just don't do it because ...
  • Julio César Fernández Muñoz
    Julio César Fernández Muñoz over 9 years
    Yes, it's the same solution with another example like Sulthan's said. Sorry for the duplicate. :) It's easy two people found the same way.
  • Aaron Brager
    Aaron Brager over 9 years
    @Sulthan .. is now ..< (in your assignment to range)
  • Cajunluke
    Cajunluke over 9 years
    On the shipping version of Swift, string[string.endIndex] results in EXC_BAD_INSTRUCTION apparently as string.endIndex is one place beyond the end of the string. string[string.endIndex-1] doesn't work as String.Index isn't IntegerConvertible. How do we get the last character of the string?
  • David L
    David L over 9 years
    @CajunLuke I know it's been a while since you posted this comment, but take a look at this answer. You can use var lastChar = string[string.endIndex.predecessor()]
  • Bjorn
    Bjorn over 9 years
    That seems extremely inefficient as you are copying the entire string just to get the first character. Use string[string. startIndex] instead of 0 as Sulthan pointed out.
  • Mohammad Zaid Pathan
    Mohammad Zaid Pathan about 9 years
    Unwrap string: var firstChar = Array(string!)[0] Otherwise it will say add arrayLiteral
  • mginn
    mginn about 9 years
    This should really be the accepted answer. It is efficient and clean, and works perfectly.
  • TheCodingArt
    TheCodingArt almost 9 years
    I don't believe this is clean, as a matter of fact it's a round about. I'm not quite sure which initializer in Array is used first causing this to happen (and I'm assuming it's the SequenceType initializer causing it to gather the characters of the string as individual components for the Array). This isn't explicit at all and may be corrected in the future without type casting. This also doesn't work if you use shorthand for the array via [string].first. @Sulthan's solution works best to use the baked in index values. It's far more clear on what is happening here.
  • John LaBarge
    John LaBarge almost 9 years
    Right but it doesn't do the range adaptation for slicing a string that the above solution solves so elegantly.
  • Admin
    Admin almost 9 years
    Cannot find an overload for 'advance' that accepts an argument list of type '(String.Index, T)' ... String.Index and Int aren't compatible.
  • aleclarson
    aleclarson almost 9 years
    @Barry That's more than likely because of the Swift 2.0 release. I'm not using Swift right now, so if someone could update this answer, I'm sure people would appreciate it.
  • SoftDesigner
    SoftDesigner almost 9 years
    If you see Cannot subscript a value of type 'String'... check this answer: stackoverflow.com/a/31265316/649379
  • Aaron
    Aaron over 8 years
    I am getting fatal error: can not increment endIndex
  • Sulthan
    Sulthan over 8 years
    the last operation could seriously improve performance by first getting the start index as let start = startIndex.advancedBy(r.startIndex) and using it as the starting point for end index let end = start.advanceBy(r.endIndex - r.startIndex).
  • duthen
    duthen over 8 years
    It seems you can replace return substringWithRange(Range(start: startIndex.advancedBy(r.startIndex), end: startIndex.advancedBy(r.endIndex))) by return self[Range(start: startIndex.advancedBy(r.startIndex), end: startIndex.advancedBy(r.endIndex))]
  • jowie
    jowie about 8 years
    When I try to use this, I get Ambiguous use of 'subscript'.
  • Craig.Pearce
    Craig.Pearce about 8 years
    @aleclarson Looks like this will have some issues with Swift 3. init(start:end:) is deprecated.
  • nekonari
    nekonari almost 8 years
    Why are you using "==="? That's identity operator for objects not comparing values..
  • ignaciohugog
    ignaciohugog almost 8 years
    WARNING! The extension below is horribly inefficient. Every time a string is accessed with an integer, an O(n) function to advance its starting index is run. Running a linear loop inside another linear loop means this for loop is accidentally O(n2) — as the length of the string increases, the time this loop takes increases quadratically. Instead of doing that you could use the characters's string collection.
  • Randel S
    Randel S almost 8 years
    @ignaciohugog Do you think String.CharacterView.Index.successor() is O(1) or O(N)? I couldn't find any O() info for .successor() or .predecessor(). Thanks.
  • Devin Brown
    Devin Brown almost 8 years
    fatal error: Can't form a Character from an empty String
  • Jack
    Jack almost 8 years
    Can I add this to a utilities file I am making that I eventually wish to pass to GitHub?
  • Thomas
    Thomas over 7 years
    I'm getting a couple errors when trying to use this with xCode 8
  • allenlinli
    allenlinli over 7 years
    May I ask what is "self[index(startIndex, offsetBy: i)]"? And how does "self[i]" work?
  • Frank
    Frank over 7 years
    Wow, compiler segment fault!
  • Ahmet Akkök
    Ahmet Akkök over 7 years
    Hi Leo, thank you for the solution! I just (today) switched to from Swift 2.3 to 3 and your solution subscript(range: Range<Int>) gives the error "Extra argument 'limitedBy' in call". What do you think can be wrong?
  • Leo Dabus
    Leo Dabus over 7 years
    @AhmetAkkök are you sure you didn't change the code?
  • Ahmet Akkök
    Ahmet Akkök over 7 years
    @Leo it turned out I did not convert the whole project but on the app not the extension, I'have repeated the process for both app and the extension and it works OK now. Your help is very much appreciated!
  • Dan Rosenstark
    Dan Rosenstark over 7 years
    this is very complicated code. What's the advantage over doing return String(Array(characters)[range]) in Swift 3?
  • BennX
    BennX about 7 years
    For those who get Ambiguous use of 'subscript' typehint to the variable type since "someString"[5] can either return a String or a Character with the shown subscripts. You need to tell him what you need. @jowie
  • Matt Le Fleur
    Matt Le Fleur about 7 years
    This doesn't work with Swift 3: argument type 'String' does not conform to expected type 'Sequence'. You would need to get the CharacterView for the string first, then index into its array: Array(str.characters)[0], or String(Array(str.characters)[0]) if you want to keep the String type.
  • rmaddy
    rmaddy almost 7 years
    This fails for many Emoji and other characters that actually take up more than once "character" in an NSString.
  • rmaddy
    rmaddy almost 7 years
    This will fail for characters that need more storage than 16 bits. Basically, any Unicode character beyond U+FFFF.
  • Leo Dabus
    Leo Dabus over 6 years
    the only disadvantage is CountableClosedRange will offset both indexes from the startIndex
  • Leo Dabus
    Leo Dabus over 6 years
    change range.upperBound - range.lowerBound to range.count
  • Chris Prince
    Chris Prince over 6 years
    It's not part of the original question, but... it would be nice if this supported assignment too. E.g., s[i] = "a" :).
  • Leo Dabus
    Leo Dabus about 6 years
    stackoverflow.com/a/38215613/4573247 now extends StringProtocol to support Substrings as well
  • Noah Wilder
    Noah Wilder about 6 years
    Why did you choose to return SubSequence rather than a value like SubString or String?
  • Leo Dabus
    Leo Dabus about 6 years
    I am extending the protocol not the type (String) so you need to return SubSequence which in the case of a String is a Substring.
  • mfaani
    mfaani about 6 years
    I'm confused. So is there any case where the Swift3 answer won't work? If not what Apple did makes no sense
  • Noah Wilder
    Noah Wilder about 6 years
    Check out my answer, it uses the same thing (credit to @alecarlson), but you can get and set the subscript.
  • leanne
    leanne over 5 years
    Works in Swift 4.1
  • Leo Dabus
    Leo Dabus over 5 years
    This method as it is unnecessarily offsetting both bounds from the startIndex. What you should do to avoid that is offset the endIndex starting from the start (not the startIndex) offsetBy the range count. Regarding the StringProtocol subscript extension I have already posted it.
  • Leo Dabus
    Leo Dabus over 5 years
    Swift 4.2 DefaultBidirectionalIndices has been renamed to DefaultIndices
  • aleclarson
    aleclarson over 5 years
    @LeoDabus I edited my answer to recommend yours. Good work!
  • Leo Dabus
    Leo Dabus over 5 years
    @aleclarson Just change startIndex to start and upperBound to count when defining the end index. This is probably the reason of 20 downvotes. Also cast Character to Character in your Swift 3 version is pointless
  • aleclarson
    aleclarson over 5 years
    @LeoDabus Feel free to make those edits yourself instead of telling me to do so. :)
  • Leo Dabus
    Leo Dabus over 5 years
    Not yet. May be in 10-14 days from now. Are you coding on linux?
  • dfrib
    dfrib over 5 years
    @LeoDabus I see. Yes mostly linux but not much Swift these days :/ I use swiftenv when I do, though, I guess it will be updated with 4.2 also somewhat soon then.
  • C0D3
    C0D3 over 5 years
    Do you mind writing something that compiles for Swift 4? last return ... line doesn't seem to work advance() function is not there I believe.
  • C0D3
    C0D3 over 5 years
    I believe with Swift 4.2 subscripts are not available again. I get an error saying: 'subscript' is unavailable: cannot subscript String with an Int, see the documentation comment for discussion
  • Leo Dabus
    Leo Dabus over 5 years
    @ChrisPrince extension StringProtocol where Self: RangeReplaceableCollection { subscript(offset: Int) -> Element { get { return self[index(startIndex, offsetBy: offset)] } set { let start = index(startIndex, offsetBy: offset) replaceSubrange(start..<index(after: start), with: [newValue]) } } }
  • Leo Dabus
    Leo Dabus over 5 years
    This is unnecessarily offsets both indexes (start and end) from the startIndex. You could simply offset the end index using the range.count and offset the start index
  • Michael
    Michael over 5 years
    @ignaciohugog wait. I think it ends up being more like O(n!)
  • Eric Aya
    Eric Aya about 5 years
    Same solution already given by Sreekanth G, Matt Le Fleur and others. And your version is worse because it doesn't convert back the result to a string.
  • bibble triple
    bibble triple about 5 years
    but it doesnt have to thats for the person to decide what they want to do with the result
  • Eric Aya
    Eric Aya about 5 years
    I understand what you say. But the second part of my comment was just an addition to the first part, which was the real important part: this solution has already been given in other answers. Please don't post what has already been posted. Don't post duplicate content, that's all I'm saying. puts each letters of your string into arrrays is already the solution given by Sreekanth G and others. Literally the same.
  • OhadM
    OhadM over 4 years
    Simplest solution and now with Swift 5 example :)
  • Pedram
    Pedram over 4 years
    Please edit your answer and add some context by explaining how your answer solves the problem, instead of posting code-only answer. From Review
  • Cristik
    Cristik over 4 years
    Why doing the unnecessary offset-ing? Why not simply string[string.startIndex]? BTW, the code would not correctly behave/compile, as you used two different variable names.
  • Cristik
    Cristik over 4 years
    Shouldn't a method named retrieveFirstCharacter return a Character?
  • Cristik
    Cristik over 4 years
    Note that this solution will result in contents duplication, making it less performant memory wise and CPU-wise.
  • Cristik
    Cristik over 4 years
    For a simple task like this one, the solution poses performance issues, as the whole contents of the string will be duplicated in memory.
  • Cristik
    Cristik over 4 years
    Duplicating the whole string contents to another memory location is counter-performant, especially for large strings. We should not need extra memory allocations for simple tasks like direct memory access.
  • Cristik
    Cristik over 4 years
    Creating an Array just to access an element seems like over-engineering, and also has performance costs as the string contents will have to be duplicated in memory.
  • Emre Değirmenci
    Emre Değirmenci over 4 years
    I want to use Java charAt(i) usage in my Swift string traverse within for loop without writing extension or another loop. How can I do ?
  • dfrib
    dfrib over 4 years
    @LeoDabus thanks for updating this answer to modern Swift!
  • Leo Dabus
    Leo Dabus over 4 years
    I think you will like this one stackoverflow.com/questions/59887561/…
  • dfrib
    dfrib over 4 years
    @LeoDabus nice work! Will have to look into the details at a later time, but I do recall that I never liked that we had to fall back on Foundation some of the ordered/countable set types.
  • Ammar Mujeeb
    Ammar Mujeeb over 4 years
    This should be built-in functions
  • James Wang
    James Wang over 4 years
    Why Swift make string so hard to use? Only Swift support Unicode? I think modern languages such Java, Javascript should all support Unicode, why their String is way easier to use?
  • James Wang
    James Wang over 4 years
    Most time user use short string , so efficiency is not an issue at all. Swift shouldn't make Swift String so hard to use, just see How Java String handle Unicode so user-friendly
  • nalexn
    nalexn over 4 years
    @JamesWang this is done for compatibility with different String character systems. Characters may take a different number of bytes, based on encoding, and there is no simple solution if you want both convenience of the API and best performance and memory consumption.
  • Leo Dabus
    Leo Dabus about 4 years
    This will convert the whole string into an array of characters every time you call this property to extract a single character from it.
  • Leo Dabus
    Leo Dabus about 4 years
    @Linh Dao Don't use encodedOffset. encodedOffset is deprecated: encodedOffset has been deprecated as most common usage is incorrect.
  • Leo Dabus
    Leo Dabus about 4 years
    @OhadM simplest doesn't mean it is correct or at least it won't work as you expect Try let flags = "🇺🇸🇧🇷" flags[String.Index(utf16Offset: 4, in: flags)] // "🇧🇷"
  • Leo Dabus
    Leo Dabus about 4 years
    This is unnecessarily offsets both indexes (start and end) from the startIndex. You could simply offset the end index using the range.count and offset the start index
  • OhadM
    OhadM about 4 years
    @LeoDabus, There are many solutions for a question and each solution solves it differently and can help other devs for other problems.
  • Leo Dabus
    Leo Dabus about 4 years
    @OhadM My comment was just a warning. Fell free to use it if you think that it behaves how you expect.
  • Tilak Madichetti
    Tilak Madichetti about 4 years
    Whatever you guys discussing it's an O(n) operation, just because it works doesn't mean you should use it . But it really depends on how frequently you are accessing the first character and how long really the string is. Anyways I wanted to throw it out there in case anyone is wondering or needs help .
  • iaomw
    iaomw almost 4 years
    That looks like O(n).
  • Abhishek Binniwale
    Abhishek Binniwale over 3 years
    This trick worked for me too . I am converting character into string back . Swift5 : var stringAtIndex = String(Array(inputString)[index])
  • Peter Schorn
    Peter Schorn over 3 years
    i ..< i + 1 should be changed to i...i.
  • Surjeet Rajput
    Surjeet Rajput about 3 years
    what will be the time complexity of doing this ?
  • multitudes
    multitudes about 3 years
    The time complexity is the same as doing it in code with let firstChar = string[string.index(string.startIndex, offsetBy: 0)]
  • Leo Dabus
    Leo Dabus almost 3 years
    This is exactly what is being done at the accepted answer. The only difference is that you are extending String instead of the StringProtocol (which supports substrings as well) and returning a string instead of a character which is totally unexpected considering that it should return the collection element which in this case is a character
  • Eric
    Eric about 2 years
    Also let stringArray: [String] = myString { String($0) }; stringArray[0] works too.