How to trim a string in Swift

How to trim a string in Swift

String trimming is one of those operations that we, as programmers, do quite often. Let's see how to trim a String using Swift.

Trim leading spaces

extension String {
    func trimingLeadingSpaces(using characterSet: CharacterSet = .whitespacesAndNewlines) -> String {
        guard let index = firstIndex(where: { !CharacterSet(charactersIn: String($0)).isSubset(of: characterSet) }) else {
            return self
        }

        return String(self[index...])
    }
}

// Usage

let trimmedStr = "  Hello World ".trimingLeadingSpaces() // returns "Hello World "

First we go to the beginning of a string to find the first character that is not a whitespace or new line using the firstIndex(where:) method. Once we find one, we're removing leading whitespaces by creating a substring from first non-whitespace character till the end of the string.

Trim trailing spaces

extension String { 
   func trimingTrailingSpaces(using characterSet: CharacterSet = .whitespacesAndNewlines) -> String {
        guard let index = lastIndex(where: { !CharacterSet(charactersIn: String($0)).isSubset(of: characterSet) }) else {
            return self
        }

        return String(self[...index])
    }
}

// Usage

let trimmedStr = "  Hello World ".trimingTrailingSpaces() // returns "  Hello World"

To remove trailing whitespaces we use the same method as for leading spaces, but we go from the end of a string.

Trim leading and trailing spaces

extension String {
    func trimmingLeadingAndTrailingSpaces(using characterSet: CharacterSet = .whitespacesAndNewlines) -> String {
        return trimmingCharacters(in: characterSet)
    }
}

// Usage

let trimmedStr = "  Hello World ".trimmingLeadingAndTrailingSpaces() // returns "Hello World"

To remove leading and trailing spaces, we use the trimmingCharacters(in:) method that removes all characters in provided character set. In our case, it removes all trailing and leading whitespaces, and new lines.

Trim all spaces

extension String {
    func trimmingAllSpaces(using characterSet: CharacterSet = .whitespacesAndNewlines) -> String {
        return components(separatedBy: characterSet).joined()
    }
}

// Usage

let trimmedStr = "  Hello World ".trimmingAllSpaces() // returns "HelloWorld"

To remove all whitespaces from a string, we split it using components(separatedBy:) method to get all the parts that don't have a whitespace. Then we  join them together using joined() method.

Putting it all together

Now, we have four functions that allow to trim a String in a specific situations. Although those functions are perfectly fine, I prefer one function that does the trimming. Here is a String extension that allows to trim a String using just one generic method:

extension String {
    enum TrimmingOptions {
        case all
        case leading
        case trailing
        case leadingAndTrailing
    }
    
    func trimming(spaces: TrimmingOptions, using characterSet: CharacterSet = .whitespacesAndNewlines) ->  String {
        switch spaces {
        case .all: return trimmingAllSpaces(using: characterSet)
        case .leading: return trimingLeadingSpaces(using: characterSet)
        case .trailing: return trimingTrailingSpaces(using: characterSet)
        case .leadingAndTrailing:  return trimmingLeadingAndTrailingSpaces(using: characterSet)
        }
    }
    
    private func trimingLeadingSpaces(using characterSet: CharacterSet) -> String {
        guard let index = firstIndex(where: { !CharacterSet(charactersIn: String($0)).isSubset(of: characterSet) }) else {
            return self
        }

        return String(self[index...])
    }
    
    private func trimingTrailingSpaces(using characterSet: CharacterSet) -> String {
        guard let index = lastIndex(where: { !CharacterSet(charactersIn: String($0)).isSubset(of: characterSet) }) else {
            return self
        }

        return String(self[...index])
    }
    
    private func trimmingLeadingAndTrailingSpaces(using characterSet: CharacterSet) -> String {
        return trimmingCharacters(in: characterSet)
    }
    
    private func trimmingAllSpaces(using characterSet: CharacterSet) -> String {
        return components(separatedBy: characterSet).joined()
    }
}

And this is how to use it:

let string = "  Hello World "

let withoutLeadingSpaces = string.trimming(spaces: .leading) // "Hello World "
let withoutTrailingSpaces = string.trimming(spaces: .trailing) // "   Hello World"
let withoutLeadingAndTrailingSpaces = string.trimming(spaces: .leadingAndTrailing) // "Hello World"
let withoutAllSpaces = string.trimming(spaces: .all) // "HelloWorld"

This is it. I hope this was useful and now you know how to trim a String in Swift.


Comments

Anything interesting to share? Write a comment.