817

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.

Naresh
  • 16,698
  • 6
  • 112
  • 113
blee908
  • 12,165
  • 10
  • 34
  • 41
  • 16
    Hi, i dont have my Mac to check. But you can try 'fullName.componentsSeparatedByString(string:" ")' Dont copy and paste, use the autocompletefunction, so you get the right function. – David Gölzhäuser Sep 05 '14 at 04:08
  • If you are only splitting by one character, using `fullName.utf8.split( )` works as well (replace `.utf8` with `.utf16` for UTF-16). For example, splitting on `+` could be done using `fullName.utf8.split(43)` – Jojodmo Dec 25 '15 at 07:41
  • Also, sometimes last names have spaces in them, as in "Daphne du Maurier" or "Charles de Lint" – Berry Jul 27 '17 at 16:45
  • I found this nice: [Split a string by single delimiter](http://programming-review.com/swift/strings/#split-a-string-by-single-delimiter), [String splitting by multiple delimiters](http://programming-review.com/swift/strings/#string-splitting-by-multiple-delimiters), [String splitting by word delimiter](http://programming-review.com/swift/strings/#string-splitting-by-word-delimiter) – prosti Jan 31 '20 at 11:31

41 Answers41

1187

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]
jr.root.cs
  • 185
  • 1
  • 15
Chen-Tsu Lin
  • 22,876
  • 16
  • 53
  • 63
827

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 
swiftBoy
  • 35,607
  • 26
  • 136
  • 135
Ethan
  • 18,584
  • 15
  • 51
  • 72
  • 104
    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. – Casey Perkins Nov 25 '14 at 13:58
  • 10
    As of Xcode 6.2b3 _split_ can be used as `split("a:b::c:", {$0 == ":"}, maxSplit: Int.max, allowEmptySlices: false)`. – Pascal Jan 07 '15 at 15:46
  • 15
    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 Feb 17 '15 at 18:29
  • @chrisco Could you say why this solution is preferred over the `componentsSeparatedByString` approach ? Regards – Pieter Meiresone Apr 19 '15 at 01:23
  • @Ethan: If I want to use either "," or ";" as split characters, how can I modify your code? – Kashif May 19 '15 at 18:37
  • 3
    @Kashif then you could use `split("a,b;c,d") {$0 == "," || $0 == ";"}` or `split("a,b;c,d") {contains(",;", $0)}` – Ethan May 20 '15 at 05:04
  • This answer doesn't wirk anymore as of Xcode7 beta5, see answers below – Lars Blumberg Sep 16 '15 at 16:12
  • 4
    Correct code for Xcode 7.0 is let fullNameArr = fullName.characters.split{$0 == " "}.map(String.init). Tried to edit, but it got rejected. – skagedal Sep 22 '15 at 19:35
  • 1
    for Swift 2: Xcode 7, fullNameArr[0] and fullNameArr[1] returns characterview – KTPatel Sep 29 '15 at 07:17
  • 1
    Answer need to be updated with comment from @skagedal because otherwise you have CharacterView instead of string but question was about string. – John Tracid Oct 01 '15 at 11:20
  • Geez, can't they make a .split() function like in Python already? – sudo Oct 20 '15 at 22:13
  • The method for Xcode 7.0 no longer works in Xcode 7.1. – sudo Nov 01 '15 at 04:50
  • 1
    @Ethan: How can I split on "; " It only seems to allow one character for split? – Kashif Nov 02 '15 at 21:18
  • 1
    Using XCode 7.2 I got an error and I think @LeoDabus answer is more Swift. – Cody Weaver Dec 13 '15 at 01:07
  • 2
    Anyone know how to split with more than 1 character? e.g. `". "` – He Yifei 何一非 Dec 13 '15 at 02:37
  • 2
    How about editing out the old stuff and just showing the current answer. People who need a history lesson can check the edit history. – Suragch Apr 25 '16 at 10:33
  • Can you add explanation to your Syntax usage? What is `$0 == " "`? – mfaani Aug 16 '16 at 16:27
  • 1
    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. – Louis Lac Sep 16 '19 at 15:23
211

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]
Panda
  • 6,955
  • 6
  • 40
  • 55
Wyetro
  • 8,439
  • 9
  • 46
  • 64
  • Is this documented anywhere, Maury? What if I need to split on something other than a single character? – NRitH Feb 17 '15 at 18:30
  • 13
    @NRitH consider `.componentsSeparatedByCharactersInSet(.whitespaceAndNewlineCharacterSet())` – rmp251 May 13 '15 at 22:56
  • @Crashalot there are two functions: `componentsSeparatedByString` and `componentsSeparatedByCharactersInSet` – rmp251 Jul 16 '15 at 23:43
  • @MdRais you should ask a new question, this one is 6 years old – Wyetro Jul 23 '20 at 20:17
160

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"]
odemolliens
  • 2,581
  • 2
  • 32
  • 34
LugiHaue
  • 2,702
  • 1
  • 15
  • 13
  • 9
    Make sure to add `import Foundation` to the class you're using this in. #SavedYouFiveMinutes – Adrian Feb 06 '17 at 23:46
  • 4
    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. – OderWat Aug 21 '17 at 22:41
  • 2
    Any multi-character splits in Swift 4+? – pkamb Sep 07 '18 at 00:35
79

Update for Swift 5.2 and the simpliest way

let paragraph = "Bob hit a ball, the hit BALL flew far after it was hit. Hello! Hie, How r u?"

let words = paragraph.components(separatedBy: [",", " ", "!",".","?"])

This prints,

["Bob", "hit", "a", "ball", "", "the", "hit", "BALL", "flew", "far", "after", "it", "was", "hit", "", "Hello", "", "Hie", "", "How", "r", "u", ""]

However, if you want to filter out empty string,

let words = paragraph.components(separatedBy: [",", " ", "!",".","?"]).filter({!$0.isEmpty})

Output,

["Bob", "hit", "a", "ball", "the", "hit", "BALL", "flew", "far", "after", "it", "was", "hit", "Hello", "Hie", "How", "r", "u"]

But make sure, Foundation is imported.

Mithra Singam
  • 1,905
  • 20
  • 26
  • 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. – Nikolay Suvandzhiev Feb 10 '21 at 10:23
71

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"
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
  • 3
    @DarrellRoot you just need to map the substrings `fullName.split { $0.isWhitespace }.map(String.init)` – Leo Dabus Jul 18 '19 at 03:13
  • 2
    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. – Darrell Root Jul 18 '19 at 05:19
58

As an alternative to WMios's answer, you can also use componentsSeparatedByCharactersInSet, which can be handy in the case you have more separators (blank space, comma, etc.).

With your specific input:

let separators = NSCharacterSet(charactersInString: " ")
var fullName: String = "First Last";
var words = fullName.componentsSeparatedByCharactersInSet(separators)

// words contains ["First", "Last"]

Using multiple separators:

let separators = NSCharacterSet(charactersInString: " ,")
var fullName: String = "Last, First Middle";
var words = fullName.componentsSeparatedByCharactersInSet(separators)

// words contains ["Last", "First", "Middle"]
Wyetro
  • 8,439
  • 9
  • 46
  • 64
Antonio
  • 71,651
  • 11
  • 148
  • 165
  • 3
    Most useful answer in my view, since you might want to allow separation of strings with `,` or `;` or any other separator – Chris Jun 04 '15 at 13:29
  • @MdRais you can use `for:in` to access the individual characters in a string - note that each element is a `Character` – Antonio Jul 24 '20 at 08:24
  • This should be the accepted answer. The accepted answers don't split by whitespace, they only split by the space character. – Sam Mar 21 '23 at 15:46
51

Swift 4

let words = "these words will be elements in an array".components(separatedBy: " ")
Bobby
  • 6,115
  • 4
  • 35
  • 36
40

The whitespace issue

Generally, people reinvent this problem and bad solutions over and over. Is this a space? " " and what about "\n", "\t" or some unicode whitespace character that you've never seen, in no small part because it is invisible. While you can get away with

A weak solution

import Foundation
let pieces = "Mary had little lamb".componentsSeparatedByString(" ")

If you ever need to shake your grip on reality watch a WWDC video on strings or dates. In short, it is almost always better to allow Apple to solve this kind of mundane task.

Robust Solution: Use NSCharacterSet

The way to do this correctly, IMHO, is to use NSCharacterSet since as stated earlier your whitespace might not be what you expect and Apple has provided a whitespace character set. To explore the various provided character sets check out Apple's NSCharacterSet developer documentation and then, only then, augment or construct a new character set if it doesn't fit your needs.

NSCharacterSet whitespaces

Returns a character set containing the characters in Unicode General Category Zs and CHARACTER TABULATION (U+0009).

let longerString: String = "This is a test of the character set splitting system"
let components = longerString.components(separatedBy: .whitespaces)
print(components)
Cameron Lowell Palmer
  • 21,528
  • 7
  • 125
  • 126
  • 2
    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. – Nicolas Miari Jul 01 '16 at 02:23
38

In Swift 4.2 and Xcode 10

//This is your str
let str = "This is my String" //Here replace with your string

Option 1

let items = str.components(separatedBy: " ")//Here replase space with your value and the result is Array.
//Direct single line of code
//let items = "This is my String".components(separatedBy: " ")
let str1 = items[0]
let str2 = items[1]
let str3 = items[2]
let str4 = items[3]
//OutPut
print(items.count)
print(str1)
print(str2)
print(str3)
print(str4)
print(items.first!)
print(items.last!)

Option 2

let items = str.split(separator: " ")
let str1 = String(items.first!)
let str2 = String(items.last!)
//Output
print(items.count)
print(items)
print(str1)
print(str2)

Option 3

let arr = str.split {$0 == " "}
print(arr)

Option 4

let line = "BLANCHE:   I don't want realism. I want magic!"
print(line.split(separator: " "))
// Prints "["BLANCHE:", "I", "don\'t", "want", "realism.", "I", "want", "magic!"]"

By Apple Documentation....

let line = "BLANCHE:   I don't want realism. I want magic!"
print(line.split(separator: " "))
// Prints "["BLANCHE:", "I", "don\'t", "want", "realism.", "I", "want", "magic!"]"

print(line.split(separator: " ", maxSplits: 1))//This can split your string into 2 parts
// Prints "["BLANCHE:", "  I don\'t want realism. I want magic!"]"

print(line.split(separator: " ", maxSplits: 2))//This can split your string into 3 parts

print(line.split(separator: " ", omittingEmptySubsequences: false))//array contains empty strings where spaces were repeated.
// Prints "["BLANCHE:", "", "", "I", "don\'t", "want", "realism.", "I", "want", "magic!"]"

print(line.split(separator: " ", omittingEmptySubsequences: true))//array not contains empty strings where spaces were repeated.
print(line.split(separator: " ", maxSplits: 4, omittingEmptySubsequences: false))
print(line.split(separator: " ", maxSplits: 3, omittingEmptySubsequences: true))
Naresh
  • 16,698
  • 6
  • 112
  • 113
25

Only the split is the correct answer, here are the difference for more than 2 spaces.

Swift 5

var temp = "Hello world     ni hao"
let arr  = temp.components(separatedBy: .whitespacesAndNewlines)
// ["Hello", "world", "", "", "", "", "ni", "hao"]
let arr2 = temp.components(separatedBy: " ")
// ["Hello", "world", "", "", "", "", "ni", "hao"]
let arr3 = temp.split(whereSeparator: {$0 == " "})
// ["Hello", "world", "ni", "hao"]
mistdon
  • 1,773
  • 16
  • 14
23

Swift 4 makes it much easier to split characters, just use the new split function for Strings.

Example: let s = "hi, hello" let a = s.split(separator: ",") print(a)

Now you got an array with 'hi' and ' hello'.

cmilr
  • 379
  • 4
  • 13
  • Note that this do not return an array of String, but array of Substring which is awkward to use. – Lirik Feb 20 '19 at 22:52
21

Swift 3

let line = "AAA    BBB\t CCC"
let fields = line.components(separatedBy: .whitespaces).filter {!$0.isEmpty}
  • Returns three strings AAA, BBB and CCC
  • Filters out empty fields
  • Handles multiple spaces and tabulation characters
  • If you want to handle new lines, then replace .whitespaces with .whitespacesAndNewlines
tepl
  • 411
  • 3
  • 4
18

Swift 4, Xcode 10 and iOS 12 Update 100% working

let fullName = "First Last"    
let fullNameArr = fullName.components(separatedBy: " ")
let firstName = fullNameArr[0] //First
let lastName = fullNameArr[1] //Last

See the Apple's documentation here for further information.

Sazzad Hissain Khan
  • 37,929
  • 33
  • 189
  • 256
Xcodian Solangi
  • 2,342
  • 5
  • 24
  • 52
14

Xcode 8.0 / Swift 3

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

var firstname = fullNameArr[0] // First
var lastname = fullNameArr[1] // Last

Long Way:

var fullName: String = "First Last"
fullName += " " // this will help to see the last word

var newElement = "" //Empty String
var fullNameArr = [String]() //Empty Array

for Character in fullName.characters {
    if Character == " " {
        fullNameArr.append(newElement)
        newElement = ""
    } else {
        newElement += "\(Character)"
    }
}


var firsName = fullNameArr[0] // First
var lastName = fullNameArr[1] // Last
NikaE
  • 614
  • 1
  • 8
  • 15
11

Most of these answers assume the input contains a space - not whitespace, and a single space at that. If you can safely make that assumption, then the accepted answer (from bennett) is quite elegant and also the method I'll be going with when I can.

When we can't make that assumption, a more robust solution needs to cover the following siutations that most answers here don't consider:

  • tabs/newlines/spaces (whitespace), including recurring characters
  • leading/trailing whitespace
  • Apple/Linux (\n) and Windows (\r\n) newline characters

To cover these cases this solution uses regex to convert all whitespace (including recurring and Windows newline characters) to a single space, trims, then splits by a single space:

Swift 3:

let searchInput = "  First \r\n \n \t\t\tMiddle    Last "
let searchTerms = searchInput 
    .replacingOccurrences(
        of: "\\s+",
        with: " ",
        options: .regularExpression
    )
    .trimmingCharacters(in: .whitespaces)
    .components(separatedBy: " ")

// searchTerms == ["First", "Middle", "Last"]
uɥƃnɐʌuop
  • 14,022
  • 5
  • 58
  • 61
10

I had a scenario where multiple control characters can be present in the string I want to split. Rather than maintain an array of these, I just let Apple handle that part.

The following works with Swift 3.0.1 on iOS 10:

let myArray = myString.components(separatedBy: .controlCharacters)
CodeBender
  • 35,668
  • 12
  • 125
  • 132
9

I found an Interesting case, that

method 1

var data:[String] = split( featureData ) { $0 == "\u{003B}" }

When I used this command to split some symbol from the data that loaded from server, it can split while test in simulator and sync with test device, but it won't split in publish app, and Ad Hoc

It take me a lot of time to track this error, It might cursed from some Swift Version, or some iOS Version or neither

It's not about the HTML code also, since I try to stringByRemovingPercentEncoding and it's still not work

addition 10/10/2015

in Swift 2.0 this method has been changed to

var data:[String] = featureData.split {$0 == "\u{003B}"}

method 2

var data:[String] = featureData.componentsSeparatedByString("\u{003B}")

When I used this command, it can split the same data that load from server correctly


Conclusion, I really suggest to use the method 2

string.componentsSeparatedByString("")
Sruit A.Suk
  • 7,073
  • 7
  • 61
  • 71
  • 1
    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. – rickster Jul 29 '15 at 19:08
9

Steps to split a string into an array in Swift 4.

  1. assign string
  2. based on @ splitting.

Note: variableName.components(separatedBy: "split keyword")

let fullName: String = "First Last @ triggerd event of the session by session storage @ it can be divided by the event of the trigger."
let fullNameArr = fullName.components(separatedBy: "@")
print("split", fullNameArr)
TylerH
  • 20,799
  • 66
  • 75
  • 101
9

This gives an array of split parts directly

var fullNameArr = fullName.components(separatedBy:" ")

then you can use like this,

var firstName: String = fullNameArr[0]
var lastName: String? = fullnameArr[1]
YodagamaHeshan
  • 4,996
  • 2
  • 26
  • 36
8

Or without closures you can do just this in Swift 2:

let fullName = "First Last"
let fullNameArr = fullName.characters.split(" ")
let firstName = String(fullNameArr[0])
Rauli Rikama
  • 126
  • 1
  • 4
  • This still works in Swift5 and fixes issues with double spaces that components(seperatedBy: " ") has. – Brett Jun 04 '23 at 08:23
6

Swift 4

let string = "loremipsum.dolorsant.amet:"

let result = string.components(separatedBy: ".")

print(result[0])
print(result[1])
print(result[2])
print("total: \(result.count)")

Output

loremipsum
dolorsant
amet:
total: 3
DoesData
  • 6,594
  • 3
  • 39
  • 62
Benjamin RD
  • 11,516
  • 14
  • 87
  • 157
5

The simplest solution is

let fullName = "First Last"

let components = fullName.components(separatedBy: .whitespacesAndNewlines).compactMap { $0.isEmpty ? nil : $0 }

This will handled multiple white spaces in a row of different types (white space, tabs, newlines etc) and only returns a two element array, you can change the CharacterSet to include more character you like, if you want to get cleaver you can use Regular Expression Decoder, this lets you write regular expression that can be used to decoded string directly into your own class/struct that implement the Decoding protocol. For something like this is over kill, but if you are using it as an example for more complicate string it may make more sense.

Nathan Day
  • 5,981
  • 2
  • 24
  • 40
4

Let's say you have a variable named "Hello World" and if you want to split it and store it into two different variables you can use like this:

var fullText = "Hello World"
let firstWord = fullText.text?.components(separatedBy: " ").first
let lastWord = fullText.text?.components(separatedBy: " ").last
Parth Barot
  • 355
  • 3
  • 9
3

This has Changed again in Beta 5. Weee! It's now a method on CollectionType

Old:

var fullName = "First Last"
var fullNameArr = split(fullName) {$0 == " "}

New:

var fullName = "First Last"
var fullNameArr = fullName.split {$0 == " "}

Apples Release Notes

Daniel H.
  • 61
  • 4
3

String handling is still a challenge in Swift and it keeps changing significantly, as you can see from other answers. Hopefully things settle down and it gets simpler. This is the way to do it with the current 3.0 version of Swift with multiple separator characters.

Swift 3:

let chars = CharacterSet(charactersIn: ".,; -")
let split = phrase.components(separatedBy: chars)

// Or if the enums do what you want, these are preferred. 
let chars2 = CharacterSet.alphaNumerics // .whitespaces, .punctuation, .capitalizedLetters etc
let split2 = phrase.components(separatedBy: chars2)
possen
  • 8,596
  • 2
  • 39
  • 48
3

I was looking for loosy split, such as PHP's explode where empty sequences are included in resulting array, this worked for me:

"First ".split(separator: " ", maxSplits: 1, omittingEmptySubsequences: false)

Output:

["First", ""]
AamirR
  • 11,672
  • 4
  • 59
  • 73
2
let str = "one two"
let strSplit = str.characters.split(" ").map(String.init) // returns ["one", "two"]

Xcode 7.2 (7C68)

Amr Lotfy
  • 2,937
  • 5
  • 36
  • 56
2

Swift 2.2 Error Handling & capitalizedString Added :

func setFullName(fullName: String) {
    var fullNameComponents = fullName.componentsSeparatedByString(" ")

    self.fname = fullNameComponents.count > 0 ? fullNameComponents[0]: ""
    self.sname = fullNameComponents.count > 1 ? fullNameComponents[1]: ""

    self.fname = self.fname!.capitalizedString
    self.sname = self.sname!.capitalizedString
}
Aqib Mumtaz
  • 4,936
  • 1
  • 36
  • 33
2

OFFTOP:

For people searching how to split a string with substring (not a character), then here is working solution:

// TESTING
let str1 = "Hello user! What user's details? Here user rounded with space."
let a = str1.split(withSubstring: "user") // <-------------- HERE IS A SPLIT
print(a) // ["Hello ", "! What ", "\'s details? Here ", " rounded with space."]

// testing the result
var result = ""
for item in a {
    if !result.isEmpty {
        result += "user"
    }
    result += item
}
print(str1) // "Hello user! What user's details? Here user rounded with space."
print(result) // "Hello user! What user's details? Here user rounded with space."
print(result == str1) // true

/// Extension providing `split` and `substring` methods.
extension String {
    
    /// Split given string with substring into array
    /// - Parameters:
    ///   - string: the string
    ///   - substring: the substring to search
    /// - Returns: array of components
    func split(withSubstring substring: String) -> [String] {
        var a = [String]()
        var str = self
        while let range = str.range(of: substring) {
            let i = str.distance(from: str.startIndex, to: range.lowerBound)
            let j = str.distance(from: str.startIndex, to: range.upperBound)
            let left = str.substring(index: 0, length: i)
            let right = str.substring(index: j, length: str.length - j)
            a.append(left)
            str = right
        }
        if !str.isEmpty {
            a.append(str)
        }
        return a
    }
    
    /// the length of the string
    public var length: Int {
        return self.count
    }
    
    /// Get substring, e.g. "ABCDE".substring(index: 2, length: 3) -> "CDE"
    ///
    /// - parameter index:  the start index
    /// - parameter length: the length of the substring
    ///
    /// - returns: the substring
    public func substring(index: Int, length: Int) -> String {
        if self.length <= index {
            return ""
        }
        let leftIndex = self.index(self.startIndex, offsetBy: index)
        if self.length <= index + length {
            return String(self[leftIndex..<self.endIndex])
        }
        let rightIndex = self.index(self.endIndex, offsetBy: -(self.length - index - length))
        return String(self[leftIndex..<rightIndex])
    }

}

Alexander Volkov
  • 7,904
  • 1
  • 47
  • 44
1

For swift 2, XCode 7.1:

let complete_string:String = "Hello world"
let string_arr =  complete_string.characters.split {$0 == " "}.map(String.init)
let hello:String = string_arr[0]
let world:String = string_arr[1]
abinop
  • 3,153
  • 5
  • 32
  • 46
1

Here is an algorithm I just build, which will split a String by any Character from the array and if there is any desire to keep the substrings with splitted characters one could set the swallow parameter to true.

Xcode 7.3 - Swift 2.2:

extension String {

    func splitBy(characters: [Character], swallow: Bool = false) -> [String] {

        var substring = ""
        var array = [String]()
        var index = 0

        for character in self.characters {

            if let lastCharacter = substring.characters.last {

                // swallow same characters
                if lastCharacter == character {

                    substring.append(character)

                } else {

                    var shouldSplit = false

                    // check if we need to split already
                    for splitCharacter in characters {
                        // slit if the last character is from split characters or the current one
                        if character == splitCharacter || lastCharacter == splitCharacter {

                            shouldSplit = true
                            break
                        }
                    }

                    if shouldSplit {

                        array.append(substring)
                        substring = String(character)

                    } else /* swallow characters that do not equal any of the split characters */ {

                        substring.append(character)
                    }
                }
            } else /* should be the first iteration */ {

                substring.append(character)
            }

            index += 1

            // add last substring to the array
            if index == self.characters.count {

                array.append(substring)
            }
        }

        return array.filter {

            if swallow {

                return true

            } else {

                for splitCharacter in characters {

                    if $0.characters.contains(splitCharacter) {

                        return false
                    }
                }
                return true
            }
        }
    }
}

Example:

"test text".splitBy([" "]) // ["test", "text"]
"test++text--".splitBy(["+", "-"], swallow: true) // ["test", "++" "text", "--"]
DevAndArtist
  • 4,971
  • 1
  • 23
  • 48
1

Simple way to split a string into array

var fullName: String = "First Last";

var fullNameArr = fullName.componentsSeparatedByString(" ")

var firstName: String = fullNameArr[0]
var lastName: String = fullNameArr[1]
Hetali Adhia
  • 506
  • 3
  • 13
0

As per Swift 2.2

You just write 2 line code and you will get the split string.

let fullName = "FirstName LastName"
var splitedFullName = fullName.componentsSeparatedByString(" ")
print(splitedFullName[0])
print(splitedFullName[1]) 

Enjoy. :)

Gautam Sareriya
  • 1,833
  • 19
  • 30
  • 2
    Same answer as http://stackoverflow.com/a/25678505/2227743 on this page. Please **read the other answers before posting yours**. Thank you. – Eric Aya Apr 26 '16 at 14:24
0

I haven't found the solution that would handle names with 3 or more components and support older iOS versions.

struct NameComponentsSplitter {

    static func split(fullName: String) -> (String?, String?) {
        guard !fullName.isEmpty else {
            return (nil, nil)
        }
        let components = fullName.components(separatedBy: .whitespacesAndNewlines)
        let lastName = components.last
        let firstName = components.dropLast().joined(separator: " ")
        return (firstName.isEmpty ? nil : firstName, lastName)
    }
}

Passed test cases:

func testThatItHandlesTwoComponents() {
    let (firstName, lastName) = NameComponentsSplitter.split(fullName: "John Smith")
    XCTAssertEqual(firstName, "John")
    XCTAssertEqual(lastName, "Smith")
}

func testThatItHandlesMoreThanTwoComponents() {
    var (firstName, lastName) = NameComponentsSplitter.split(fullName: "John Clark Smith")
    XCTAssertEqual(firstName, "John Clark")
    XCTAssertEqual(lastName, "Smith")

    (firstName, lastName) = NameComponentsSplitter.split(fullName: "John Clark Jr. Smith")
    XCTAssertEqual(firstName, "John Clark Jr.")
    XCTAssertEqual(lastName, "Smith")
}

func testThatItHandlesEmptyInput() {
    let (firstName, lastName) = NameComponentsSplitter.split(fullName: "")
    XCTAssertEqual(firstName, nil)
    XCTAssertEqual(lastName, nil)
}
Vadim Bulavin
  • 3,697
  • 25
  • 19
0
let fullName : String = "Steve.Jobs"
let fullNameArr : [String] = fullName.components(separatedBy: ".")

var firstName : String = fullNameArr[0]
var lastName : String = fullNameArr[1]
Sai kumar Reddy
  • 1,751
  • 20
  • 23
  • 1
    Some explanation about why this produces the desired results would be helpful. – joanolo Jul 28 '17 at 14:41
  • Please give some explanation, it's always better to do so. – Kundan Jul 28 '17 at 16:36
  • **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](https://meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers). – help-info.de Jul 28 '17 at 18:59
  • here fullName is a string separated by a "." using fullName.components(separatedBy: ".") default apple provided function and it returns an array of string – Sai kumar Reddy Dec 23 '19 at 07:16
0
var fullName = "James Keagan Michael"
let first = fullName.components(separatedBy: " ").first?.isEmpty == false ? fullName.components(separatedBy: " ").first! : "John"
let last =  fullName.components(separatedBy: " ").last?.isEmpty == false && fullName.components(separatedBy: " ").last != fullName.components(separatedBy: " ").first ? fullName.components(separatedBy: " ").last! : "Doe"
  • Disallow same first and last name
  • If a fullname is invalid, take placeholder value "John Doe"
jnblanchard
  • 1,182
  • 12
  • 12
0

Expounding off of Don Vaughn's Answer, I liked the use of Regular Expressions. I'm surprised that this is only the 2nd Regex answer. However, if we could solve this in just one split method, instead of multiple methods, that would be great.

I was also inspired by Mithra Singam's Answer to exclude all punctuation as well as whitespace. However, having to create a list of disallowed characters didn't vibe with me.

  • \w - Regular Expression for a Letter or Number symbol. No punctuation.
let foo = "(..#   Hello,,(---- World   ".split {
    String($0).range(of: #"\w"#, options: .regularExpression) == nil
}
print(foo) // Prints "Hello World"

Let's say you aren't comfortable will all of Unicode. How about just ASKII Letters and Numbers?

let bar = "(..#   Hello,,(---- World   ".split {
    !($0.isASCII && ($0.isLetter || $0.isNumber))
}
print(bar) // Prints "Hello World"
0-1
  • 702
  • 1
  • 10
  • 30
0

Do not use whitespace to separate words. It will not work well for English. And it will not work at all for languages like Japanese or Chinese.

Here is a sample for tokenizing names from a given string:

import NaturalLanguage

actor Tokenizer {
    private let tagger = NLTagger(tagSchemes: [.nameType])

    func tokens(for text: String) async -> [String] {
        tagger.string = text

        let tags = tagger.tags(
            in: text.startIndex ..< text.endIndex,
            unit: .word,
            scheme: .nameType,
            options: [
                .omitPunctuation,
                .omitWhitespace,
                .joinNames,
            ]
        )

        return tags.map { String(text[$1]) }
    }
}
Max Potapov
  • 1,267
  • 11
  • 17
-2

You can use this common function and add any string which you want to separate

func separateByString(String wholeString: String, byChar char:String) -> [String] {

    let resultArray = wholeString.components(separatedBy: char)
    return resultArray
}

var fullName: String = "First Last"
let array = separateByString(String: fullName, byChar: " ")
var firstName: String = array[0]
var lastName: String = array[1]
print(firstName)
print(lastName)
blackstorm
  • 60
  • 10
  • 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. – Eric Aya Dec 03 '18 at 18:07
-2

This is for String and CSV file for swift 4.2 at 20181206 1610

var dataArray : [[String]] = []
 let path = Bundle.main.path(forResource: "csvfilename", ofType: "csv")
        let url = URL(fileURLWithPath: path!)
        do {
            let data = try Data(contentsOf: url) 
            let content = String(data: data, encoding: .utf8)
            let parsedCSV = content?.components(separatedBy: "\r\n").map{ $0.components(separatedBy: ";") }
           for line in parsedCSV!
            {
                dataArray.append(line)
           }
        }
        catch let jsonErr {
            print("\n   Error read CSV file: \n ", jsonErr)
        }

            print("\n MohNada 20181206 1610 - The final result is \(dataArray)  \n ")