John
John

Reputation: 1015

Turn Swift function into extension for reuse

I would like to remove specific characters from a string - instead of reentering the following across various string in my application, I would like to create an extension to easily reference across the code.

How can this be turned into an extension?

var string = "11224B"
let removeCharacters: Set<Character> = [" ", ";", ".", "!", "/"]
string.removeAll(where: { removeCharacters.contains($0) })
print(string)

Upvotes: 0

Views: 231

Answers (2)

Leo Dabus
Leo Dabus

Reputation: 236420

What you need is to extend the protocol which requires you to implement removeAll(where:) method, in this case RangeReplaceableCollection and constrain Self to StringProtocol:


extension RangeReplaceableCollection where Self: StringProtocol {
    mutating func remove(characters: Set<Element>) {
        removeAll(where: characters.contains)
    }
}

var string = "1/1!2.2;4 B"
string.remove(characters: [" ", ";", ".", "!", "/"])
print(string)  // "11224B\n"

And the non mutating method as well but using filter instead. You just need to return Self:

extension RangeReplaceableCollection where Self: StringProtocol {
    func removing(characters: Set<Element>) -> Self {
        filter { !characters.contains($0) }
    }
}

let string = "1/1!2.2;4 B"
string.removing(characters: [" ", ";", ".", "!", "/"]) // "11224B\n"

You can also make your method generic and allow any sequence type which its element is equal to the collection element type:


extension RangeReplaceableCollection where Self: StringProtocol {
    mutating func remove<S: Sequence>(characters: S) where S.Element == Element {
        removeAll(where: characters.contains)
    }
    func removing<S: Sequence>(characters: S) -> Self where S.Element == Element {
        filter { !characters.contains($0) }
    }
}

var string = "1/1!2.2;4 B"
let characters: Set<Character> = [" ", ";", ".", "!", "/"]
string.remove(characters: characters) 
string // "11224B\n"

let string = "1/1!2.2;4 B"
let charactersString = " ;.!/"
string.removing(characters: charactersString) // "11224B\n"

Upvotes: 2

RTXGamer
RTXGamer

Reputation: 3742

Extension:

extension String {
    func removeCharacters(from characterSet: CharacterSet) -> String {
        let filteredString = self.unicodeScalars.filter { !characterSet.contains($0) }
        return String(String.UnicodeScalarView(filteredString))
    }
}

Usage:

var string1 = "1122 ;4B"
print(string1.removeCharacters(from: [" ", ";", ".", "!", "/"]))

Use removeCharacters as default parameter:

extension String {
    func removeCharacters(from characterSet: CharacterSet = [" ", ";", ".", "!", "/"]) -> String {
        let filteredString = self.unicodeScalars.filter { !characterSet.contains($0) }
        return String(String.UnicodeScalarView(filteredString))
    }
}

var string1 = "1122 ;4B"
print(string1.removeCharacters())

Upvotes: 1

Related Questions