Split string on ANY character of a character set - ios

Is it possible to take a string and do a split based on an character in a character set?
let sourceString = "This is the original string/sentence."
let nonAlphabet = NSCharacterSet(charactersInString: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz").invertedSet
// let words = sourceString.split(charSet:nonAlphabet)
In this case words = ["This","is","the","original","string","sentence"]
Is this possible?

(NS)String has a method componentsSeparatedByCharactersInSet
let words = sourceString.componentsSeparatedByCharactersInSet(nonAlphabet)
The result will have an empty string at the end of the array because of the period.

let s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
let ss = "This is the original string/sentence."
let arr = ss.characters.split{!s.characters.contains($0)}.map{String($0)}
// ["This", "is", "the", "original", "string", "sentence"]

Related

How to remove first word from a sentence in swift

I know how to remove first character from a word in swift like this:
var data = "CITY Singapore"
data.removeFirst()
print(data)//ITY Singapore
what i want is to remove the first word and space so the result is "Singapore".
How can i remove the first word and leading space in swift?
You can try
let data = "CITY Singapore"
let res = data.components(separatedBy: " ").dropFirst().joined(separator: " ")
print(res)
Or
let res = data[data.range(of: " ")!.upperBound...] // may crash for no " " inside the string
Or you can go with this too
let strData = "CITY Singapore"
if let data = strData.components(separatedBy: " ").dropFirst().first {
// do with data
}
else {
// fallback
}
This is a Regular Expression solution, the benefit is to modify the string in place.
The pattern searches from the beginning of the string to the first space character
var data = "CITY Singapore"
if let range = data.range(of: "^\\S+\\s", options: .regularExpression) {
data.removeSubrange(range)
}
You can use String's enumerateSubstrings in range method (Foundation) using byWords option and remove the first enclosing range. You need also to stop enumeration after removing the range at the first occurrence:
var string = "CITY Singapore"
string.enumerateSubstrings(in: string.startIndex..., options: .byWords) { (_, _, enclosingRange, stop) in
string.removeSubrange(enclosingRange)
stop = true
}
string // "Singapore"

Swift. Get first name and last initial from a name string [duplicate]

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.
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]
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
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]
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"]
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.
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"
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"]
Swift 4
let words = "these words will be elements in an array".components(separatedBy: " ")
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)
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))
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"]
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'.
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
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.
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
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"]
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)
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("")
Steps to split a string into an array in Swift 4.
assign string
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)
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]
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])
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
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.
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
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
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)
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", ""]
let str = "one two"
let strSplit = str.characters.split(" ").map(String.init) // returns ["one", "two"]
Xcode 7.2 (7C68)
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
}
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])
}
}

Getting specific range of characters from a string swift 3

i would like to get specific characters from my string, like this for example
var str = "hey steve #steve123, you would love this!"
// Without doing this
var theCharactersIWantFromTheString = "#steve123"
How would i just retrieve the #steve123 from str
You can use regular expression "\\B\\#\\w+".
let pattern = "\\B\\#\\w+"
let sentence = "hey steve #steve123, you would love this!"
if let range = sentence.range(of: pattern, options: .regularExpression) {
print(sentence.substring(with: range)) // "#steve123\n"
}

Swift separate String into array of data split at certain characters [duplicate]

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.
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]
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
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]
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"]
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.
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"
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"]
Swift 4
let words = "these words will be elements in an array".components(separatedBy: " ")
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)
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))
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"]
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'.
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
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.
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
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"]
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)
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("")
Steps to split a string into an array in Swift 4.
assign string
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)
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]
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])
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
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.
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
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
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)
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", ""]
let str = "one two"
let strSplit = str.characters.split(" ").map(String.init) // returns ["one", "two"]
Xcode 7.2 (7C68)
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
}
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])
}
}

Split a String into an array in Swift?

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.
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]
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
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]
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"]
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.
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"
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"]
Swift 4
let words = "these words will be elements in an array".components(separatedBy: " ")
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)
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))
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"]
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'.
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
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.
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
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"]
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)
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("")
Steps to split a string into an array in Swift 4.
assign string
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)
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]
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])
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
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.
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
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
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)
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", ""]
let str = "one two"
let strSplit = str.characters.split(" ").map(String.init) // returns ["one", "two"]
Xcode 7.2 (7C68)
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
}
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])
}
}

Resources