Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

Scalaの遅延評価(lazy)を関数オブジェクトで使ってみる

More than 1 year has passed since last update.

概要

Scalaでよく使う遅延評価(lazy)を、関数オブジェクトに適用して、処理効率を上げてみたときの内容をサンプルコードにまとめます。なお、遅延評価の詳細についてはプログラミング言語Scala 日本語情報サイト 第 14 章 遅延評価valを参照ください。

例題

以下が処理効率化する前のサンプルコードです。partitionの中で本来一度で済むはずのOptionの空判定やSeqのlengthメソッドの呼び出しを、ループ回数分だけ行っています。なお、partitionについては@f81@githubさんの第10章:Scalaの「Traversable」リファレンスを参照ください。

Before.scala
  def testBefore(judgeOpt: Option[Int]) = {
    val numberList = Seq(1,2,3,4,5,6,7,8,9,10)

    val (leftList,rightList) = numberList.partition{ n =>
      if (judgeOpt.isEmpty) {
        false
      } else if (judgeOpt.get > numberList.length) {
        true
      } else {
        if (n % judgeOpt.get == 0) {
          false
        } else {
          true
        }
      }
    }
    println(leftList)
  }

lazyを使ったサンプルコード

対応として1つ目と2つ目のブロックをあらかじめBooleanで評価するという手もありますが、今回はlazyを用いて処理の効率化を実現してみます。
下記のサンプルコードの通り、関数オブジェクトを遅延評価する関数(judgeFunction)を作成しpartition内で使用する判定関数を一度の評価で決定します。なお、judgeFunction中の「println("None")」や「println("Over")」は一度しか処理されません。

After.scala
  def testAfter(judgeOpt: Option[Int]) = {
    val numberList = Seq(1,2,3,4,5,6,7,8,9,10)
    def judgeFunction(judgeOpt: Option[Int], list: Seq[Int]):(Int) => Boolean = {
      if (judgeOpt.isEmpty) {
        println("None")
        (_: Int) => false
      } else if (judgeOpt.get > list.length) {
        println("Over")
        (_: Int) => true
      } else {
        divideFuncton(_: Int, judgeOpt.get)
      }
    }
    def divideFuncton(target: Int, input: Int):Boolean = {
      if (target % input == 0) {
        false
      } else {
        true
      }
    }

    lazy val f = judgeFunction(judgeOpt, numberList)
    val (leftList,rightList) = numberList.partition{ n =>
      f(n)
    }
    println(leftList)
  }
someone7140
まだまだ修行中のエンジニアです。ちゃんとサービスを作れるようになりたいです。
http://toaruit.hatenablog.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away