LoginSignup
9
8

More than 5 years have passed since last update.

ScalaでFizzBuzz

Last updated at Posted at 2016-04-12

はじめに

FizzBuzzを題材に、一昔前のJavaのような命令型記法から段階を踏んでScalaらしく(関数型っぽく)リファクタリングしてみました。

if式

書き換えのスタート地点。if式(※)を使って判定を行っている。
※Scalaはifも値を返却するため、if文ではなくif式という。同様にforもfor文ではなくfor式。

FizzBuzz.scala
for(i <- 1 to 100) {
  if(i % 3 == 0 && i % 5 == 0) {
    println("FizzBuzz")
  }else if (i % 3 == 0) {
    println("Fizz")
  }else if (i % 5 == 0) {
    println("Buzz")
  }else {
    println(i)
  }
}

パターンマッチ&パターンガード(if)

if式をパターンマッチに書き換え。パターンマッチ内にガード条件(if)を記述することができる。

FizzBuzz.scala
for(i <- 1 to 100) i match {
  // パターンマッチ & ガード条件
  case i if x % 3 == 0 && i % 5 == 0 => println("FizzBuzz")
  case i if x % 3 == 0 => println("Fizz")
  case i if x % 5 == 0 => println("Buzz")
  case _ => println(i)
}

タプルを使ったパターンマッチ

タプルを使い、判定条件の左辺(剰余計算)と右辺(0)をパターンマッチの入力と判定(case部)に分解する。

FizzBuzz.scala
for(i <- 1 to 100) (i % 3, i % 5) match {
  case (0, 0) => println("FizzBuzz")
  case (0, _) => println("Fizz")
  case (_, 0) => println("Buzz")
  case _      => println(i)
}

メソッドに切り出す

FizzBuzz変換と出力(println)を分割し、メソッドに切り出す。
呼び出し時に関数合成することで、再利用性が高くなり仕様変更にも柔軟に対応できる。

FizzBuzz.scala
def fizzbuzz(i: Int) = (i % 3, i % 5) match {
  case (0, 0) => "FizzBuzz"
  case (0, _) => "Fizz"
  case (_, 0) => "Buzz"
  case _      => i
}

// 呼び出し
(1 to 100).map(fizzbuzz).foreach(println)

9
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
8