Split a String into an array in Swift?
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."
}
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"
blee908
Updated on July 18, 2022Comments
-
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 over 9 yearsIn 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 over 9 yearsAs of Xcode 6.2b3 split can be used as
split("a:b::c:", {$0 == ":"}, maxSplit: Int.max, allowEmptySlices: false)
. -
NRitH about 9 yearsJust 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 saylet (firstName, lastName) = split(fullName) {$0 == ' '}
, that doesn't work, sadly. -
NRitH about 9 yearsIs this documented anywhere, Maury? What if I need to split on something other than a single character?
-
Pieter Meiresone about 9 years@chrisco Could you say why this solution is preferred over the
componentsSeparatedByString
approach ? Regards -
rmp251 about 9 years@NRitH consider
.componentsSeparatedByCharactersInSet(.whitespaceAndNewlineCharacterSet())
-
Kashif almost 9 years@Ethan: If I want to use either "," or ";" as split characters, how can I modify your code?
-
Ethan almost 9 years@Kashif then you could use
split("a,b;c,d") {$0 == "," || $0 == ";"}
orsplit("a,b;c,d") {contains(",;", $0)}
-
Can almost 9 yearsBe noted that this is actually an underlying
NSString
(Swift automatically swaps them when importingFoundation
). -
Chris almost 9 yearsMost useful answer in my view, since you might want to allow separation of strings with
,
or;
or any other separator -
elcuco almost 9 yearsWhich is no longer the case in Swift 1.2, in which Apple no longer converts Swift's String into NSString automagically.
-
rmp251 almost 9 years@Crashalot there are two functions:
componentsSeparatedByString
andcomponentsSeparatedByCharactersInSet
-
Frizlab almost 9 years@Crashalot This answer does not work starting from Swift 1.2.
-
Andrew almost 9 yearsThis 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 almost 9 yearsI'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 over 8 yearsThis answer doesn't wirk anymore as of Xcode7 beta5, see answers below
-
skagedal over 8 yearsCorrect code for Xcode 7.0 is let fullNameArr = fullName.characters.split{$0 == " "}.map(String.init). Tried to edit, but it got rejected.
-
KTPatel over 8 yearsfor Swift 2: Xcode 7, fullNameArr[0] and fullNameArr[1] returns characterview
-
John Tracid over 8 yearsAnswer need to be updated with comment from @skagedal because otherwise you have CharacterView instead of string but question was about string.
-
Velizar Hristov over 8 yearsIt didn't work in the REPL until I imported Foundation.
-
sudo over 8 yearsGeez, can't they make a .split() function like in Python already?
-
sudo over 8 yearsThe method for Xcode 7.0 no longer works in Xcode 7.1.
-
Kashif over 8 years@Ethan: How can I split on "; " It only seems to allow one character for split?
-
Cody Weaver over 8 yearsUsing XCode 7.2 I got an error and I think @LeoDabus answer is more Swift.
-
He Yifei 何一非 over 8 yearsAnyone know how to split with more than 1 character? e.g.
". "
-
Jon Cox over 8 yearsThis works exactly as expected (i.e. fullNameArr is an
[String]
) in Xcode 7.2. -
Suragch about 8 yearsHow 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 about 8 yearsSame answer as stackoverflow.com/a/25678505/2227743 on this page. Please read the other answers before posting yours. Thank you.
-
Bob Spryn about 8 yearsArray subscript doesn't return optionals.
var lastName: String? = fullNameArr[1]
will not work. -
Maxime Chéramy about 8 yearsIt apparently requires Foundation to work, which is no longer available in Swift 2.2.1 on Linux.
-
Nicolas Miari almost 8 yearsAgreed. 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 almost 8 yearsCan you add explanation to your Syntax usage? What is
$0 == " "
? -
Chad over 7 yearsUsing Swift 3 and XCode 8.2, I did not need to
import Foundation
. -
Adrian over 7 yearsMake sure to add
import Foundation
to the class you're using this in. #SavedYouFiveMinutes -
xxmbabanexx about 7 yearsIs there a way to split using regex? I tried to do
string.components(separatedBy: regex, options: .regularExpression)
but I got an error. -
joanolo almost 7 yearsSome explanation about why this produces the desired results would be helpful.
-
Kundan almost 7 yearsPlease give some explanation, it's always better to do so.
-
help-info.de almost 7 yearsFrom 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 over 6 yearsAttention (Swift 4): If you have a string like
let a="a,,b,c"
and you usea.split(separator: ",")
you get an array like["a", "b", c"]
by default. This can be changed usingomittingEmptySubsequences: false
which is true by default. -
pkamb over 5 yearsAny multi-character splits in Swift 4+?
-
Dani over 5 yearsHow to limit amount of parts string splits to?
-
Eric Aya over 5 yearsHi. 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 about 5 yearsNote that this do not return an array of String, but array of Substring which is awkward to use.
-
Leo Dabus almost 5 years@DarrellRoot you just need to map the substrings
fullName.split { $0.isWhitespace }.map(String.init)
-
Darrell Root almost 5 yearsI 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 over 4 yearsUsing Swift 5 in Xcode 10.3
String.components(SeparatedByString:)
is still way faster thanString.split(separator:)
. Around 4 times faster for me. Just be careful withcomponent
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 over 4 yearshere fullName is a string separated by a "." using fullName.components(separatedBy: ".") default apple provided function and it returns an array of string
-
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 almost 4 years@MdRais let name = "JOHN" print(Array(name))
-
Wyetro almost 4 years@MdRais you should ask a new question, this one is 6 years old
-
Bobby almost 4 yearsTry converting the word to a char data type.
-
Antonio almost 4 years@MdRais you can use
for:in
to access the individual characters in a string - note that each element is aCharacter
-
Nikolay Suvandzhiev over 3 yearsNote that this has different behaviour in some edge cases. For example:
"/users/4"
withsplit
will result in two elements, whereas withcomponents
, there will be three, the first one being the empty string.