Swift switch statement for matching substrings of a String

11,648

Solution 1

Swift language has two kinds of OR operators - the bitwise ones | (single vertical line), and the logical ones || (double vertical line). In this situation you need a logical OR:

if self.descriptionWeather.description.rangeOfString("Clear") != nil || self.descriptionWeather.description.rangeOfString("clear") != nil {
    self.imageWeather.image = self.soleadoImage
}

Unlike Objective-C where you could get away with a bitwise OR in exchange for getting a slightly different run-time semantic, Swift requires a logical OR in the expression above.

Solution 2

I had a similar problem today and realized this question hasn't been updated since Swift 1! Here's how I solved it in Swift 4:

switch self.descriptionWeather.description {
case let str where str.contains("Clear"):
    print("clear")
case let str where str.contains("rain"):
    print("rain")
case let str where str.contains("broken clouds"):
    print("broken clouds")
default:
    break
}

Solution 3

You can do this with a switch statement using value binding and a where clause. But convert the string to lowercase first!

var desc = "Going to be clear and bright tomorrow"

switch desc.lowercaseString as NSString {
case let x where x.rangeOfString("clear").length != 0:
    println("clear")
case let x where x.rangeOfString("cloudy").length != 0:
    println("cloudy")
default:
    println("no match")
}

// prints "clear"

Solution 4

Swift 5 Solution

func weatherImage(for identifier: String) -> UIImage? {
    switch identifier {
    case _ where identifier.contains("Clear"),
         _ where identifier.contains("rain"):
        return self.soleadoImage
    case _ where identifier.contains("broken clouds"):
        return self.nubladoImage
    default: return nil
    }
}

Solution 5

If you do this a lot, you can implement a custom ~= operator that defines sub-string matching:

import Foundation

public struct SubstringMatchSource {
    private let wrapped: String

    public init(wrapping wrapped: String) {
        self.wrapped = wrapped
    }

    public func contains(_ substring: String) -> Bool {
        return self.wrapped.contains(substring)
    }

    public static func ~= (substring: String, source: SubstringMatchSource) -> Bool {
        return source.contains(substring)
    }
}

extension String {
    var substrings: SubstringMatchSource {
        return SubstringMatchSource(wrapping: self)
    }
}

switch "abcdefghi".substrings {
    case "def": // calls `"def" ~= "abcdefghi".substrings`
        print("Found substring: def") 
    case "some other potential substring":
        print("Found \"some other potential substring\"")
    default: print("No substring matches found")
}
Share:
11,648
LPS
Author by

LPS

Updated on June 25, 2022

Comments

  • LPS
    LPS almost 2 years

    Im trying to ask for some values from a variable. The variable is going to have the description of the weather and i want to ask for specific words in order to show different images (like a sun, rain or so) The thing is i have code like this:

        if self.descriptionWeather.description.rangeOfString("Clear") != nil
    {
        self.imageWeather.image = self.soleadoImage
    }
    if self.descriptionWeather.description.rangeOfString("rain") != nil
    {
        self.imageWeather.image = self.soleadoImage
    }
    if self.descriptionWeather.description.rangeOfString("broken clouds") != nil
    {
        self.imageWeather.image = self.nubladoImage
    }
    

    Because when i tried to add an "OR" condition xcode gives me some weird errors.

    Is it possible to do a swich sentence with that? Or anyone knows how to do add an OR condition to the if clause?