Start learning free

LESSON 64 OF 415 · STRINGS I

String Split in Swift: split(separator:)

Lesson Read the full explanation

In Swift, you can split a string into an array of substrings using split(separator:). It takes a character (or a string) as the delimiter, and returns an array of Substring values:

s.split(separator: delimiter)   // splits using a delimiter

Here are some examples:

let sentence = "hello world foo"
let words = sentence.split(separator: " ")
// words == ["hello", "world", "foo"]

let csv = "a,b,c"
let parts = csv.split(separator: ",")
// parts == ["a", "b", "c"]

You can loop through the resulting array:

for w in words {
    print(w)
}

Assignment
Follow the Coding Tutorial and split sentence into an array of words!


Hint
Use sentence.split(separator: " ") and assign the result to words.

STEP 1 OF 1
    Ctrl + Enter to check

    SWIFT · STRINGS I

    String Split in Swift, explained

    Splitting a string into pieces

    To cut a string into parts at a separator, call split(separator:). It returns an array of the pieces between the separators, and the separators themselves are left out. No import is needed.

    let sentence = "hello world foo"
    let words = sentence.split(separator: " ")
    print(words)
    print(words.count)
    
    let csv = "a,b,c"
    print(csv.split(separator: ","))
    
    ["hello", "world", "foo"]
    3
    ["a", "b", "c"]
    

    You can loop over the result like any array:

    for word in words {
        print(word)
    }
    
    hello
    world
    foo
    

    The pieces are Substring values

    The array's elements are Substring values, not String. They print like strings and have most of the same methods, such as count and uppercased(). They are views into the original string, so when you need a real String, for example to store it or pass it to a function that takes one, convert with String(...):

    let words = "hello world foo".split(separator: " ")
    let first: String = String(words[0])
    let all = words.map { String($0) }
    print(first)
    print(all)
    
    hello
    ["hello", "world", "foo"]
    

    map { String($0) } converts every element at once and gives a [String].

    Empty pieces

    By default, empty pieces are dropped. Two separators in a row, or a separator at the start or end, don't produce empty strings:

    print("a,,b,".split(separator: ","))
    print("a,,b,".split(separator: ",", omittingEmptySubsequences: false))
    print("".split(separator: " ").count)
    
    ["a", "b"]
    ["a", "", "b", ""]
    0
    

    Pass omittingEmptySubsequences: false when the empty fields matter, as in a table row where a column can be blank. The empty string splits into an empty array.

    More control

    • maxSplits limits the number of cuts. The rest of the string stays in the last piece: "a,b,c,d".split(separator: ",", maxSplits: 1) gives ["a", "b,c,d"].
    • split(whereSeparator:) takes a closure, so several characters can act as separators: "a b\tc".split(whereSeparator: { $0 == " " || $0 == "\t" }) gives ["a", "b", "c"].
    • The separator may also be a longer string, such as ", ": "one, two".split(separator: ", ") gives ["one", "two"].

    Splitting numbers out of text

    A common use is reading values from a line of text. Split the line, then convert each piece with the Int initializer, which returns an optional because a piece may not be a number. compactMap keeps only the pieces that converted successfully:

    let line = "3 4 5"
    let numbers = line.split(separator: " ").map { Int($0)! }
    print(numbers, numbers.reduce(0, +))
    
    let mixed = "3 x 5".split(separator: " ").compactMap { Int($0) }
    print(mixed)
    
    [3, 4, 5] 12
    [3, 5]
    

    The ! in the first line crashes if any piece isn't a number, so it suits input you trust. For input you don't control, prefer compactMap, which skips the bad pieces, or check each result yourself.

    Splitting and joining

    The opposite operation is joined(separator:) on an array of strings. Splitting a sentence and joining the words with another separator rewrites the separators: "hello world foo".split(separator: " ").joined(separator: "-") gives hello-world-foo. This works on the array of Substring values directly, so no conversion is needed first.

    The exercise

    The constant sentence holds "hello world foo". Declare words with let and split the sentence at each space. The loop already in the starter code prints one word per line.

            let sentence = "hello world foo"
    
            let words = sentence.split(separator: " ")
            for word in words { print(word) }
    
    hello
    world
    foo
    

    Common mistakes

    • Expecting [String]. The result holds Substring values. Assigning one to a String variable is a compile error until you wrap it in String(...).
    • Expecting empty strings. "a,,b".split(separator: ",") has two pieces, not three, unless you pass omittingEmptySubsequences: false.
    • Forgetting the label. Swift requires separator:.
    • Splitting on the wrong character. A line from a file may end with a newline, or words may be separated by a tab; use split(whereSeparator:) then.

    Key takeaways

    • split(separator:) returns an array of Substring values and leaves out the separators.
    • Empty pieces are omitted unless you ask to keep them.
    • Use String(...) or map { String($0) } to get real strings.
    Keep going with SwiftAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free