【Scala】Scala ~ 基本編 / パターンマッチング ~

■ はじめに

Scala の パターンマッチング が強力って話が業務中にでてきたので
調べて、まとめる

目次

【0】パターンマッチング
【1】定数でのマッチング
【2】ガード条件(if)でのマッチング
【3】関数として定義
【4】データ型でのマッチング
【5】ケースクラスでのマッチング

【0】パターンマッチング

https://docs.scala-lang.org/ja/tour/pattern-matching.html

* パターンに照合するための仕組み
* マッチに成功すれば、一つの値をその構成要素のパーツに分解することもできる
* Javaのswitch文の強化バージョン

【1】定数でのマッチング

object DemoMain {
  def main(args: Array[String]): Unit = {
    val testValue = 0
    # ★ここに注目★
    val result = testValue match {
      // case 0 | -1 => "NG"
      case 0 => "NG"
      case 100 => "OK"
      case _ => "Not 0 or 100"
    }

    println(s"result: ${result}")
  }
}

【2】ガード条件(if)でのマッチング

object  Hello {
  def main(args: Array[String]): Unit = {
    val str = "1,2,3,4,5,"
    val results = str.split(",")

    // ★別解は、「【4】データ型でのマッチング」の「例2:配列数」を参照
    results.size match {
      // ★注目
      case size if size >= 2 =>
        val x1 = results(0)
        val x2 = results(1)
        println(s"${x1} - ${x2}") // 1 - 2
        // case 中の変数 size もそのまま使える
        val x3 = if (size != 5) "XX" else results(4)
        println(s"${x3}") // 5
      case _ => println("data must be more than 2")
    }
  }
}

【3】関数として定義

object DemoMain {

  def matching(testValue: Int): String = testValue match {
    case 0 => "NG"
    case 100 => "OK"
    case _ => "Not 0 or 100"
  }

  def main(args: Array[String]): Unit = {
    val testValue = 100
    val result = matching(testValue)
    println(s"result: ${result}")
  }
}

【4】データ型でのマッチング

例1:データ型

object Hello {
  def main(args: Array[String]): Unit = {
    val testValues = List(1, "Mike", true, 12.12, Array("AA", "BB"))
    for (value <- testValues) {
      value match {
        case id: Integer => println(s"id=${id}")
        case name: String => println(s"name=${name}")
        case isMale: Boolean => println(s"isMale?=${isMale}")
        case array: Array[String] => println(s"array.length=${array.length}")
        case _ => println(s"value=${value}")
      }
    }
  }
}

例2:配列数

object  Hello {
  def main(args: Array[String]): Unit = {
    val str = "Hello,World,Mike"

      str.split(",") match {
        case Array(greet) => println(s"${greet}!")
        case Array(greet,place) => println(s"${greet} ${place}!!")
        case Array(greet,place,name) => println(s"${greet} ${place}, ${name}!!")
        case _ => println("Not supported")
      }
  }
}

【5】ケースクラスでのマッチング

abstract class Week

case class Sunday() extends Week
case class Monday() extends Week
case class Tuesday() extends Week
case class Wednesday() extends Week
case class Thursday() extends Week
case class Friday() extends Week
case class Saturday() extends Week

object DemoMain {
  def sayTodaysWeek(week: Week): String = {
    week match {
      case Saturday() => "Today is Saturday"
      case Sunday() => "Today is Sunday"
      case _ => "Today is boring day..."
    }
  }

  def main(args: Array[String]): Unit = {
    println(sayTodaysWeek(new Sunday)) 
  }
}

参考文献

https://qiita.com/f81@github/items/aa46c248a38a171ed955
https://www.tohoho-web.com/ex/scala.html#match

関連記事

Scala ~ 環境構築編 ~
https://dk521123.hatenablog.com/entry/2023/03/10/193805
Scala ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2023/03/12/184331
Scala ~ 基本編 / 文字列 ~
https://dk521123.hatenablog.com/entry/2023/01/07/000000
Scala ~ 基本編 / 正規表現
https://dk521123.hatenablog.com/entry/2023/03/18/034704
Scala ~ 基本編 / Either型 ~
https://dk521123.hatenablog.com/entry/2023/08/02/132315
ScalaEnum
https://dk521123.hatenablog.com/entry/2023/01/05/000000