Is it possible to use a value binding with a where clause in a switch case statement?

Hello!, I'm making a package which processes public transport routes and categorises them based on the identifier of the route in question. The public transport network in question is for Chicago and each route entry can be categorised in one of four ways:

  1. Train lines have specific string identifiers "red" for the Red Line, "blue" for the Blue Line, etc (these don't always match the names of the lines but are regular enough such that hard coding values in particular way is not too difficult to manage since the adding and removing of lines is a relatively infrequent occurrence)
  2. There are three systemwide "route" entries that represent the global status as impacted by situations that apply on a relatively unilateral basis to all routes. Of these three categories, there is one for all routes (bus and train), one for all bus routes, and one for all train lines. These follow a similar convention to the train lines
  3. Individual train stations are input as route entries whose identifiers are always integers between 40000 and 49999.
  4. Since bus routes don't fit in as nicely a category I simply have them at the moment just trying to match the other three cases before defaulting to being a bus route. However, it appears that all bus routes (except for one part time route that may not appear in the data feed I'm working with) match with the regular expression ([A-Z]?[0-9]+[A-Z]?)

My initial question pertained more so to stations and how to best write cleaner code for this but seeing that the way I am doing this at the moment could negatively impair performance to a possibly problematic level in the future, I'm wondering how exactly I should do this. My current code is as follows:

switch self.id {
case "Red", "Blue", "Brn", "G", "Org", "P", "Pexp", "Pink", "Y":
    self.type = .trainRoute
case "Systemwide", "Bus", "Train":
    self.type = .systemwideCategory
case let idString:
    guard let id = Int(idString), (40000..<50000).contains(id) else {
        fallthrough
    }
    self.type = .trainStation
default:
    self.type = .busRoute
}

For the third switch case, is it possible to replace the first of the following blocks (with guard statement) with the second (guard statement replaced by more complicated switch case)?

case let idString:
    guard let id = Int(idString), (40000..<50000).contains(id) else {
case let idString where let id = Int(idString), (40000..<50000).contains(id):

My second, and more broader, question with my situation is whether there might be a better way to process this. Since a fully numeric bus route has to go through 12 equality comparisons, one type conversion, and two inequality comparisons before being categorised as a bus route, I feel that this may pose a undue performance cost. This is especially considering the existence of about ~130 bus routes on the system of which about ~110 are fully numeric.

Yes, but not using the question that is the title of this post.

type = switch id {
case "Red", "Blue", "Brn", "G", "Org", "P", "Pexp", "Pink", "Y":
  .trainRoute
case "Systemwide", "Bus", "Train":
  .systemwideCategory
case _ where Int(id).map((40000..<50000).contains) == true:
    .trainStation
default:
  .busRoute
}
1 Like

Thanks for your input. I'm thinking of using a Dictionary to store the individual identifiers for the train routes and systemwide categories since it would permit me to directly match these situations through what could be up to 12 different equality checks, are there any downsides of this approach such as space constraints?