Split a String into an array in Swift?

664,321

Solution 1

The Swift way is to use the global split function, like so:

var fullName = "First Last"
var fullNameArr = split(fullName) {$0 == " "}
var firstName: String = fullNameArr[0]
var lastName: String? = fullNameArr.count > 1 ? fullNameArr[1] : nil

with Swift 2

In Swift 2 the use of split becomes a bit more complicated due to the introduction of the internal CharacterView type. This means that String no longer adopts the SequenceType or CollectionType protocols and you must instead use the .characters property to access a CharacterView type representation of a String instance. (Note: CharacterView does adopt SequenceType and CollectionType protocols).

let fullName = "First Last"
let fullNameArr = fullName.characters.split{$0 == " "}.map(String.init)
// or simply:
// let fullNameArr = fullName.characters.split{" "}.map(String.init)

fullNameArr[0] // First
fullNameArr[1] // Last 

Solution 2

Just call componentsSeparatedByString method on your fullName

import Foundation

var fullName: String = "First Last"
let fullNameArr = fullName.componentsSeparatedByString(" ")

var firstName: String = fullNameArr[0]
var lastName: String = fullNameArr[1]

Update for Swift 3+

import Foundation

let fullName    = "First Last"
let fullNameArr = fullName.components(separatedBy: " ")

let name    = fullNameArr[0]
let surname = fullNameArr[1]

Solution 3

The easiest method to do this is by using componentsSeparatedBy:

For Swift 2:

import Foundation
let fullName : String = "First Last";
let fullNameArr : [String] = fullName.componentsSeparatedByString(" ")

// And then to access the individual words:

var firstName : String = fullNameArr[0]
var lastName : String = fullNameArr[1]

For Swift 3:

import Foundation

let fullName : String = "First Last"
let fullNameArr : [String] = fullName.components(separatedBy: " ")

// And then to access the individual words:

var firstName : String = fullNameArr[0]
var lastName : String = fullNameArr[1]

Solution 4

Swift Dev. 4.0 (May 24, 2017)

A new function split in Swift 4 (Beta).

import Foundation
let sayHello = "Hello Swift 4 2017";
let result = sayHello.split(separator: " ")
print(result)

Output:

["Hello", "Swift", "4", "2017"]

Accessing values:

print(result[0]) // Hello
print(result[1]) // Swift
print(result[2]) // 4
print(result[3]) // 2017

Xcode 8.1 / Swift 3.0.1

Here is the way multiple delimiters with array.

import Foundation
let mathString: String = "12-37*2/5"
let numbers = mathString.components(separatedBy: ["-", "*", "/"])
print(numbers)

Output:

["12", "37", "2", "5"]

Solution 5

Swift 4 or later

If you just need to properly format a person name, you can use PersonNameComponentsFormatter.

The PersonNameComponentsFormatter class provides localized representations of the components of a person’s name, as represented by a PersonNameComponents object. Use this class to create localized names when displaying person name information to the user.


// iOS (9.0 and later), macOS (10.11 and later), tvOS (9.0 and later), watchOS (2.0 and later)
let nameFormatter = PersonNameComponentsFormatter()

let name =  "Mr. Steven Paul Jobs Jr."
// personNameComponents requires iOS (10.0 and later)
if let nameComps  = nameFormatter.personNameComponents(from: name) {
    nameComps.namePrefix   // Mr.
    nameComps.givenName    // Steven
    nameComps.middleName   // Paul
    nameComps.familyName   // Jobs
    nameComps.nameSuffix   // Jr.

    // It can also be configured to format your names
    // Default (same as medium), short, long or abbreviated

    nameFormatter.style = .default
    nameFormatter.string(from: nameComps)   // "Steven Jobs"

    nameFormatter.style = .short
    nameFormatter.string(from: nameComps)   // "Steven"

    nameFormatter.style = .long
    nameFormatter.string(from: nameComps)   // "Mr. Steven Paul Jobs jr."

    nameFormatter.style = .abbreviated
    nameFormatter.string(from: nameComps)   // SJ

    // It can also be use to return an attributed string using annotatedString method
    nameFormatter.style = .long
    nameFormatter.annotatedString(from: nameComps)   // "Mr. Steven Paul Jobs jr."
}

enter image description here

edit/update:

Swift 5 or later

For just splitting a string by non letter characters we can use the new Character property isLetter:

let fullName = "First Last"

let components = fullName.split{ !$0.isLetter }
print(components)  // "["First", "Last"]\n"
Share:
664,321
blee908
Author by

blee908

Updated on July 18, 2022

Comments

  • blee908
    blee908 almost 2 years

    Say I have a string here:

    var fullName: String = "First Last"
    

    I want to split the string base on white space and assign the values to their respective variables

    var fullNameArr = // something like: fullName.explode(" ") 
    
    var firstName: String = fullNameArr[0]
    var lastName: String? = fullnameArr[1]
    

    Also, sometimes users might not have a last name.

  • Casey Perkins
    Casey Perkins over 9 years
    In my tests, componentsSeparatedByString is usually significantly faster, especially when dealing with strings that require splitting into many pieces. But for the example listed by the OP, either should suffice.
  • Pascal
    Pascal over 9 years
    As of Xcode 6.2b3 split can be used as split("a:b::c:", {$0 == ":"}, maxSplit: Int.max, allowEmptySlices: false).
  • NRitH
    NRitH about 9 years
    Just remember that you still need to use the old componentsSeparatedByString() method if your separator is anything longer than a single character. And as cool as it would be to say let (firstName, lastName) = split(fullName) {$0 == ' '}, that doesn't work, sadly.
  • NRitH
    NRitH about 9 years
    Is this documented anywhere, Maury? What if I need to split on something other than a single character?
  • Pieter Meiresone
    Pieter Meiresone about 9 years
    @chrisco Could you say why this solution is preferred over the componentsSeparatedByString approach ? Regards
  • rmp251
    rmp251 about 9 years
    @NRitH consider .componentsSeparatedByCharactersInSet(.whitespaceAndNewlineC‌​haracterSet())
  • Kashif
    Kashif almost 9 years
    @Ethan: If I want to use either "," or ";" as split characters, how can I modify your code?
  • Ethan
    Ethan almost 9 years
    @Kashif then you could use split("a,b;c,d") {$0 == "," || $0 == ";"} or split("a,b;c,d") {contains(",;", $0)}
  • Can
    Can almost 9 years
    Be noted that this is actually an underlying NSString (Swift automatically swaps them when importing Foundation).
  • Chris
    Chris almost 9 years
    Most useful answer in my view, since you might want to allow separation of strings with , or ; or any other separator
  • elcuco
    elcuco almost 9 years
    Which is no longer the case in Swift 1.2, in which Apple no longer converts Swift's String into NSString automagically.
  • rmp251
    rmp251 almost 9 years
    @Crashalot there are two functions: componentsSeparatedByString and componentsSeparatedByCharactersInSet
  • Frizlab
    Frizlab almost 9 years
    @Crashalot This answer does not work starting from Swift 1.2.
  • Andrew
    Andrew almost 9 years
    This answer works in Xcode 7 beta 4 and Swift 2.0. Xcode now auto-completes Foundation methods on Swift String objects without type casting to an NSString, which is not the case in Xcode 6.4 with Swift 1.2.
  • rickster
    rickster almost 9 years
    I'd say this is close to "not an answer" status, in that it's mostly commentary on existing answers. But it is pointing out something important.
  • Lars Blumberg
    Lars Blumberg over 8 years
    This answer doesn't wirk anymore as of Xcode7 beta5, see answers below
  • skagedal
    skagedal over 8 years
    Correct code for Xcode 7.0 is let fullNameArr = fullName.characters.split{$0 == " "}.map(String.init). Tried to edit, but it got rejected.
  • KTPatel
    KTPatel over 8 years
    for Swift 2: Xcode 7, fullNameArr[0] and fullNameArr[1] returns characterview
  • John Tracid
    John Tracid over 8 years
    Answer need to be updated with comment from @skagedal because otherwise you have CharacterView instead of string but question was about string.
  • Velizar Hristov
    Velizar Hristov over 8 years
    It didn't work in the REPL until I imported Foundation.
  • sudo
    sudo over 8 years
    Geez, can't they make a .split() function like in Python already?
  • sudo
    sudo over 8 years
    The method for Xcode 7.0 no longer works in Xcode 7.1.
  • Kashif
    Kashif over 8 years
    @Ethan: How can I split on "; " It only seems to allow one character for split?
  • Cody Weaver
    Cody Weaver over 8 years
    Using XCode 7.2 I got an error and I think @LeoDabus answer is more Swift.
  • He Yifei 何一非
    He Yifei 何一非 over 8 years
    Anyone know how to split with more than 1 character? e.g. ". "
  • Jon Cox
    Jon Cox over 8 years
    This works exactly as expected (i.e. fullNameArr is an [String]) in Xcode 7.2.
  • Suragch
    Suragch about 8 years
    How about editing out the old stuff and just showing the current answer. People who need a history lesson can check the edit history.
  • Eric Aya
    Eric Aya about 8 years
    Same answer as stackoverflow.com/a/25678505/2227743 on this page. Please read the other answers before posting yours. Thank you.
  • Bob Spryn
    Bob Spryn about 8 years
    Array subscript doesn't return optionals. var lastName: String? = fullNameArr[1] will not work.
  • Maxime Chéramy
    Maxime Chéramy about 8 years
    It apparently requires Foundation to work, which is no longer available in Swift 2.2.1 on Linux.
  • Nicolas Miari
    Nicolas Miari almost 8 years
    Agreed. The first thing that occurred to me after seeing the answers that split by " " is: What happens if the input text contains several consecutive spaces? What if it has tabs? Full-width (CJK) space? etc.
  • mfaani
    mfaani almost 8 years
    Can you add explanation to your Syntax usage? What is $0 == " "?
  • Chad
    Chad over 7 years
    Using Swift 3 and XCode 8.2, I did not need to import Foundation.
  • Adrian
    Adrian over 7 years
    Make sure to add import Foundation to the class you're using this in. #SavedYouFiveMinutes
  • xxmbabanexx
    xxmbabanexx about 7 years
    Is there a way to split using regex? I tried to do string.components(separatedBy: regex, options: .regularExpression) but I got an error.
  • joanolo
    joanolo almost 7 years
    Some explanation about why this produces the desired results would be helpful.
  • Kundan
    Kundan almost 7 years
    Please give some explanation, it's always better to do so.
  • help-info.de
    help-info.de almost 7 years
    From review queue: May I request you to please add some more context around your answer. Code-only answers are difficult to understand. It will help the asker and future readers both if you can add more information in your post. See also Explaining entirely code-based answers.
  • OderWat
    OderWat over 6 years
    Attention (Swift 4): If you have a string like let a="a,,b,c" and you use a.split(separator: ",") you get an array like ["a", "b", c"] by default. This can be changed using omittingEmptySubsequences: false which is true by default.
  • pkamb
    pkamb over 5 years
    Any multi-character splits in Swift 4+?
  • Dani
    Dani over 5 years
    How to limit amount of parts string splits to?
  • Eric Aya
    Eric Aya over 5 years
    Hi. In Swift, parameters name should always start with lowercase. Like: separateByString(string wholeString: String, byChar char:String). Also this way avoids conflating the variable name with a type.
  • Lirik
    Lirik about 5 years
    Note that this do not return an array of String, but array of Substring which is awkward to use.
  • Leo Dabus
    Leo Dabus almost 5 years
    @DarrellRoot you just need to map the substrings fullName.split { $0.isWhitespace }.map(String.init)
  • Darrell Root
    Darrell Root almost 5 years
    I love that new API but keep in mind it returns Substrings. I needed Strings (and wanted to split on whitespace in general) so I did this: let words = line.split{ $0.isWhitespace }.map{ String($0)} Thanks @LeoDabus for your version (my original comment had code missing). Also I suggest moving the Swift 5 version to the top of the answer.
  • Louis Lac
    Louis Lac over 4 years
    Using Swift 5 in Xcode 10.3 String.components(SeparatedByString:) is still way faster than String.split(separator:). Around 4 times faster for me. Just be careful with component if there is a white space of new line at the end of your string, it returns an empty string at the end of the output string array.
  • Sai kumar Reddy
    Sai kumar Reddy over 4 years
    here fullName is a string separated by a "." using fullName.components(separatedBy: ".") default apple provided function and it returns an array of string
  • Dave
    Dave almost 4 years
    @DanielSpringer That is the flaw in this approach. This is frequently cited in examples extracting class names but it doesn't account for nested types. For that scenario I prefer str.split(separator: ".", maxSplits: 1).last.map(String.init)!
  • NikaE
    NikaE almost 4 years
    @MdRais let name = "JOHN" print(Array(name))
  • Wyetro
    Wyetro almost 4 years
    @MdRais you should ask a new question, this one is 6 years old
  • Bobby
    Bobby almost 4 years
    Try converting the word to a char data type.
  • Antonio
    Antonio almost 4 years
    @MdRais you can use for:in to access the individual characters in a string - note that each element is a Character
  • Nikolay Suvandzhiev
    Nikolay Suvandzhiev over 3 years
    Note that this has different behaviour in some edge cases. For example: "/users/4" with split will result in two elements, whereas with components, there will be three, the first one being the empty string.