How to remove multiple spaces in Strings with Swift 2

Cleanest version. Documented, memory efficient, extremely easy to use.

extension String {

    /// Returns a condensed string, with no extra whitespaces and no new lines.
    var condensed: String {
        return replacingOccurrences(of: "[\\s\n]+", with: " ", options: .regularExpression, range: nil)
    }

    /// Returns a condensed string, with no whitespaces at all and no new lines.
    var extraCondensed: String {
        return replacingOccurrences(of: "[\\s\n]+", with: "", options: .regularExpression, range: nil)
    }

}

Usage:

let a = " Hello\n  I am  a string  ".condensed
let b = " Hello\n  I am  a string  ".extraCondensed

Output:

a: "Hello I am a string"

b: "HelloIamastring"


In Swift 2, join has become joinWithSeparator and you call it on the array.

In filter, isEmpty should be called on the current iteration item $0.

To replace whitespaces and newline characters with unique space characters as in your question:

extension String {
    func condenseWhitespace() -> String {
        let components = self.componentsSeparatedByCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
        return components.filter { !$0.isEmpty }.joinWithSeparator(" ")
    }
}

let result = "Hello  World.\nHello!".condenseWhitespace()  // "Hello World. Hello!"

Because your function does not take any parameter you could make it a property instead:

extension String {
    var condensedWhitespace: String {
        let components = self.componentsSeparatedByCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
        return components.filter { !$0.isEmpty }.joinWithSeparator(" ")
    }
}

let result = "Hello  World.\nHello!".condensedWhitespace  // "Hello World. Hello!"

In Swift 3 there's even more changes.

Function:

extension String {
    func condenseWhitespace() -> String {
        let components = self.components(separatedBy: NSCharacterSet.whitespacesAndNewlines)
        return components.filter { !$0.isEmpty }.joined(separator: " ")
    }
}

let result = "Hello  World.\nHello!".condenseWhitespace()

Property:

extension String {
    var condensedWhitespace: String {
        let components = self.components(separatedBy: NSCharacterSet.whitespacesAndNewlines)
        return components.filter { !$0.isEmpty }.joined(separator: " ")
    }
}

let result = "Hello  World.\nHello!".condensedWhitespace

In Swift 4.2 NSCharacterSet is now CharacterSet, and you can omit and use dot syntax:

extension String {
    func condenseWhitespace() -> String {
        let components = self.components(separatedBy: .whitespacesAndNewlines)
        return components.filter { !$0.isEmpty }.joined(separator: " ")
    }
}

let result = "Hello  World.\nHello!".condenseWhitespace()  // "Hello World. Hello!"

Split string to array and then join again in not memory efficient. Its Takes lot of memory. The best way in this case is to scan the given string and perform operations on that. Regular Expression is the advance way to scan a text. For the above conclusion the the solution is given below:

Swift 4.x

extension String {

    func removeExtraSpaces() -> String {
        return self.replacingOccurrences(of: "[\\s\n]+", with: " ", options: .regularExpression, range: nil)
    }

}

Usages

let startingString = "hello   world! \n\n I am   here!"
let processedString = startingString.removeExtraSpaces()
print(processedString)

Output:

processedString => "hello world! I am here!"

You can Do more according to your own requirements but thing I am pointing out here is to use regular expressions with string rather then create arrays which will consume lot of memory.