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.

pattern, pattern matching, swift

Published at DZone with permission of Alex Curylo , DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

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

{{ parent.tldr }}

{{ parent.urlSource.name }}