Adding trimming extension to String

Nowadays, almost every app handles user input.
Whether it’s entering user details, filling forms, sending messages or posting content, we all need to handle some text input. Sometimes with complex validation and sometimes not.

One extension I find myself adding to every codebase I work on is to trim spaces. Often before sending content to the server, because most don’t want to send leading/trailing spaces.

I propose adding this extension to the language as I believe many others would benefit from it, and it’s a very simple addition.

public extension String {
    func trimmed() -> String {
        trimmingCharacters(in: .whitespacesAndNewlines)
    }
    
    mutating func trim() {
        self = trimmed()
    }
}
3 Likes

So you've effectively:

  1. renamed "trimmingCharacters" to "trimmed"
  2. introduced the corresponding mutating method
  3. removed its parameter and hardcoded whitespacesAndNewlines

1 & 2 are ok with me so long as it is compatible with swift conventions we use in other places. 3 is strange and arbitrary, I'd leave this parameter in place, if absolutely needed make it defaulted.

PS. I have literally hundreds of helpers like this. Doesn't bother me much they are part of my library vs being part of the standard library.

1 Like

FWIW, trimmingCharacters(in:) and its CharacterSet argument are implemented in Foundation, so a pitch to add similar functionality to the standard library wouldn't be able to be implemented in terms of those.

You may want to keep an eye on https://github.com/apple/swift-experimental-string-processing. There's a lot of work being done there to improve the landscape of string processing algorithms, and it looks like they already have some generic trimming algorithms in place. Whether there would be a version that assumes whitespace as the default argument is less clear (and my guess would be less likely), though, since that's a much more opinionated/subjective choice.

4 Likes

It's in swift-algorithms: swift-algorithms/Trim.md at main · apple/swift-algorithms · GitHub

It would make sense to add this to the standard library, though - for all BidirectionalCollections, not just String. Our current slicing methods are a bit of a hodgepodge with several gaps that should be filled, and ideally they would all follow some consistent naming pattern (for example, we have drop(while:) to remove stuff from a collection's start, but no parallel for removal from the end; swift-algorithms uses trimmingPrefix and trimmingSuffix for consistency)

4 Likes

This is not meant to be a replacement. The idea is adding a common use case on top to provide a standardised implementation baked into the system.
Bottom line it’s syntactic sugar similar to toggle on a Bool.
I also have many extensions I carry over from project to project, as many others I would assume. Some are used more than others. If many people do the same or find this useful, it would be great to have it as part of the language.

It cleans up the call site so we can have less verbose code going

// From this
if let input = textfield.text?.trimmingCharacters(in: .whitespacesAndNewlines) {...}
// To this
if let input = textfield.text?.trimmed() {...}

Thanks for the reply, Tony.

My example was meant to explain the behaviour, although I would expect it to be implemented without needing to rely on Foundation.

I appreciate your input.