1

I want to write the following in a more elegant way:

let number = "1,2922.3"

if number.contains(",") || number.contains(".") && !(number.contains(".") && number.contains(",")) {
    // proceed
}

That is, I want to proceed if the number has "." or ",", but not them both.

There has to be a better way?

I don't want to use an extension, as this is in a single place in my code.

WishIHadThreeGuns
  • 1,225
  • 3
  • 17
  • 37
  • 1
    You should use an extension. Extensions are specifically for single places in your code. Always use an extension. (In some cases use a function instead, but generally an extension.) – Fattie May 17 '21 at 19:10
  • @Fattie I don't think that was the intention. The OP is stating that don't want to add an extension as this is a one-time check only - they don't want to extend a class across the board *Extensions add new functionality to an existing class, structure, enumeration, or protocol type.* [Extension](https://docs.swift.org/swift-book/LanguageGuide/Extensions.html) – Jay May 17 '21 at 19:17
  • ? you just use fileprivate – Fattie May 17 '21 at 19:19
  • Sometimes simpler is better! There's really nothing wrong with that code so it's not clear why you want to simplify it. Note there is a slight logic error in that you're want to group your OR together for evaluation as a group like this `( number.contains(",") || number.contains(".") ) && !( number.contains(".") && number.contains(",") )`. So that now reads the string contains ( . OR , ) AND does not contain both. That makes the first part to evaluate to true if , or . – Jay May 17 '21 at 19:32
  • 2
    This seems suspiciously close to validating number formats. Your idea of a "correct format" is probably wrong, so tread carefully. – Alexander May 17 '21 at 19:37

1 Answers1

5

You can use SetAlgebra:

func validate(_ string: String) -> Bool {
    let allowed = Set(",.")
    return !allowed.isDisjoint(with: string) && !allowed.isSubset(of: string)
}

validate("1,2922.3") // false
validate("1,29223") // true
validate("12922.3") // true
validate("129223") // false

To explain a bit:

  • !allowed.isDisjoint(with: string) because you want to exclude strings that contain neither . and ,.
  • !allowed.isSubset(of: string) because you want to exclude strings that contain both . and ,.
AnderCover
  • 2,488
  • 3
  • 23
  • 42