Swift: Replacing the NSString method componentsSeparatedByCharactersInSet with a combination of the split() and find() algorithms


NSString method

A Swift string instance is automatically bridged to NSString, so there's no work to be done in order to leverage the method componentsSeparatedByCharactersInSet.

let myString = "Explore #Swift: Algorithms"
let separated = myString.componentsSeparatedByCharactersInSet(NSCharacterSet(charactersInString: ":, .!"))

However, doing so we not only need to employ the method itself and the NSCharacterSet class, but often what we then have is an array not only with the values we want but also with empty strings. As Apple outlines:

Adjacent occurrences of the separator characters produce empty strings in the result. Similarly, if the string begins or ends with separator characters, the first or last substring, respectively, is empty. Apple Docs

So we then need to perform a clean-up operation to delete these empty strings.

Swift algorithms

Our alternative to relying on the Cocoa Framework, in this instance, is instead to pass one of Swift's algorithms as part of a closure to another of Swift's algorithms: find() passed to split().

let separated = split("Explore #Swift: Algorithms", {(c:Character)->Bool in find(":, .!",c) != nil}, allowEmptySlices: false)

or more succinctly:

let separated = split("Explore #Swift: Algorithms", {find(":, .!",$0) != nil}, allowEmptySlices: false)

In this way we do not need to create an NSCharacterSet and neither do we need to worry about empty strings in our array.

Note: The split() algorithm returns an array and relies on receiving a Bool as the basis of dividing the String it begins with, while find() returns the index of the Character sent to closure within the String of characters that it should split on and if this isn't nil then we return a Bool value of true.

For further discussion of generics and algorithms see the previous post, which is on split() and join().



Endorse on Coderwall

Comments