Search code examples
swift2xcode7removing-whitespace

How to remove multiple spaces in Strings with Swift 2


Until Swift 2 I used this extension to remove multiple whitespaces:

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

but with Swift 2 now I get the error

Cannot invoke 'isEmpty' with an argument list of type '(String)'

How could I now remove multiple spaces with Swift 2? Thnx!


Solution

  • 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!"