Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Complete Pattern Matching

DZone's Guide to

Complete Pattern Matching

If you've been wondering about the various ways to deal with pattern matching in Swift, there's a series of articles that can help!

· Mobile Zone ·
Free Resource

There’s a great series just wrapped up over at Crunchy Development which dives deeper into Swift pattern matching than you’ve ever been, no doubt:


Check out how expressive pattern matching can get by the end of that:

enum Media {
  case Book(title: String, author: String, year: Int)
  case Movie(title: String, director: String, year: Int)
  case WebSite(urlString: String)
}

let mediaList: [Media] = [
  .Book(title: "Harry Potter and the Philosopher's Stone", author: "J.K. Rowling", year: 1997),
  .Movie(title: "Harry Potter and the Philosopher's Stone", director: "Chris Columbus", year: 2001),
  .Book(title: "Harry Potter and the Chamber of Secrets", author: "J.K. Rowling", year: 1999),
  .Movie(title: "Harry Potter and the Chamber of Secrets", director: "Chris Columbus", year: 2002),
  .Book(title: "Harry Potter and the Prisoner of Azkaban", author: "J.K. Rowling", year: 1999),
  .Movie(title: "Harry Potter and the Prisoner of Azkaban", director: "Alfonso Cuarón", year: 2004),
  .WebSite(urlString: "https://en.wikipedia.org/wiki/List_of_Harry_Potter-related_topics")
]

extension Media {
  var title: String? {
    switch self {
    case let .Book(title, _, _): return title
    case let .Movie(title, _, _): return title
    default: return nil
    }
  }
  var kind: String {
    // Remember part 1 where we bind all the associated values in one single anonymous tuple `_`?
    switch self {
    case .Book(_): return "Book"
    case .Movie(_): return "Movie"
    case .WebSite(_): return "Web Site"
    }
  }
}

print("All mediums with a title starting with 'Harry Potter'")
for case let (title?, kind) in mediaList.map({ ($0.title, $0.kind) })
  where title.hasPrefix("Harry Potter") {
    print(" - [\(kind)] \(title)")
}


This look might look a little complex, so let’s split it down:

  • It uses map to transform the Array<Media> array mediaList into an array of tuples [(String?, String)] containing the title (if any) + the kind of item (as text)
  • It only matches if title? matches — which is syntactic sugar to say if .Some(title) matches — the $0.title of each media. This means that it discards any media for which $0.title returns nil (a.k.a. Optional.None) — excluding any webSite in the process, as those don’t have any title)
  • Then it filters the results to only iterate on those for which title.hasPrefix(“Harry Potter”) is true.

Also, note particularly in Part 3 about defining the ~= operator for your own types. Which, in case you were wondering: The pattern matching operator is pronounced “twiddle-eek” not “bacon rocket”. Not only more fun to say but tells you the order in which to type the symbols.

Topics:
swift ,pattern ,pattern matching

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}