`

Scala Comprehensions

 
阅读更多

原创转载请注明出处:http://agilestyle.iteye.com/blog/2333647

 

for和if的组合称为for推导,简称为推导。先看一个简单的例子:

package org.fool.scala.comprehension

object ComprehensionTest extends App {
  def evenGT5(v: Vector[Int]): Vector[Int] = {
    // 'var' so we can reassign 'result'
    var result = Vector[Int]()

    for {
      n <- v
      if n > 5
      if n % 2 == 0
    } result = result :+ n

    result
  }

  val v = Vector(1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 13, 15, 17, 20)
  println(evenGT5(v))
}

Note:

result为var而不是val

Vector有一个操作符“:+”,它会接受一个Vector(但是不会修改它),并将操作符右边的元素与其组合起来,以此创建一个新的Vector。

Console Output


 

有一种将result用作val(而不是var)的方式:by building result "in place" rather than creating it piece-by-piece。为了实现这个目的,可是使用Scala的yield关键字。当你声明yield n时,它会将值n "yield up"出来,使其成为result的一部分。

package org.fool.scala.comprehension

object Yielding extends App {
  def yielding(v: Vector[Int]): Vector[Int] = {
    val result = for {
      n <- v
      if n < 10
      if n % 2 != 0
    } yield n
    result
  }

  val v = Vector(1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 13, 15, 17, 20)
  println(yielding(v))
}

Console Output


 

接下来在推导内部定义值,并且不存储和返回中间结果result

package org.fool.scala.comprehension

object Yielding2 extends App {
  def yielding2(v: Vector[Int]): Vector[Int] = {
    for {
      n <- v
      if n < 10
      isOdd = (n % 2 != 0)
      if (isOdd)
    } yield n
  }

  val v = Vector(1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 13, 15, 17, 20)
  println(yielding2(v))
}

Console Output


 

与其他任何表达式一样,yield表达式也可以组合

package org.fool.scala.comprehension

object Yielding3 extends App {
  def yielding3(v: Vector[Int]): Vector[Int] = {
    for {
      n <- v
      if n < 10
      isOdd = (n % 2 != 0)
      if (isOdd)
    } yield {
      // only inside the comprehension can you get away without declaring val or var for new identifiers.
      val u = n * 10
      u + 2
    }
  }

  val v = Vector(1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 13, 15, 17, 20)
  println(yielding3(v))
}

Note:

只有在推导内部才能不为新标识符声明val或var

Console Output


 

可以将一个推导只与一个yield表达式相关联,并且不能将yield表达式置于推导体之前。但是推导可以嵌套:

package org.fool.scala.comprehension

object Yielding4 extends App {
  def yielding4(v: Vector[Int]) = {
    for {
      n <- v
      if n < 10
      isOdd = (n % 2 != 0)
      if (isOdd)
    } yield {
      for (u <- Range(0, n))
        yield u
    }
  }

  val v = Vector(1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 13, 15, 17, 20)
  println(yielding4(v))
}

Console Output


 

参考资料:

Scala编程思想 

 

 

 

 

 

  • 大小: 10.1 KB
  • 大小: 7.3 KB
  • 大小: 8.8 KB
  • 大小: 10.1 KB
  • 大小: 12 KB
分享到:
评论

相关推荐

    scala深入学习

    学习如何使用序列(Sequences)、操作序列(Working with Sequences)以及for推导式(For Comprehensions)是理解和运用Scala集合的关键。 7. 迭代和递归:在"Sequencing Computations"部分,学习者会接触到如何...

    官网下载好的 scala-2.11.8.rar

    例如,for-comprehensions可以用来简化迭代和数据转换。 5. **复合性管理**:通过使用case类和模式匹配,Scala提供了一种优雅的方式来处理复杂的数据结构和控制流。这有助于降低代码的复杂度和提高可读性。 6. **...

    Scala语言规范.zip

    5. **表达式和控制流**:Scala的控制流语句,如if-else、for-comprehensions和while循环,都是表达式,可以有返回值。此外,还有try-catch-finally用于异常处理。 6. ** Trait**:Scala的trait是一种可复用的代码块...

    scala-2.11.12.msi 安装程序

    8. **语法糖**:Scala的语法糖特性使得编写代码更加简洁,如for-comprehensions(用于迭代和集合操作)和case classes(用于模式匹配)。 9. **与Java兼容**:Scala运行在Java虚拟机(JVM)上,可以无缝与Java库...

    scala学习文档

    此外,文档可能还介绍了Scala的语法糖,如for-comprehensions,它们在表达复杂的迭代和组合时非常简洁。 02.Actor编程.docx: Scala的Actor模型是并发处理的关键组成部分,由Akka库提供支持。Actors是轻量级的线程...

    最新scala 2.9.1 final包

    6. **语法糖和语言特性**:Scala不断引入新的语法结构,如Pattern Matching、For Comprehensions等,使得代码更加简洁和易读。2.9.1 final可能添加或改进了一些语法特性。 7. **错误消息和编译器反馈**:编译器的...

    新出现的新语言scala新动向

    其次,Scala的函数式编程元素包括高阶函数、局部套用(Currying)、嵌套函数和序列解读(Sequence Comprehensions)。这些特性使得Scala能处理复杂的数据结构和算法,提供了更简洁的代码表达方式。高阶函数允许函数...

    scala PPt

    此外,Scala的for推导(comprehensions)是一种强大的循环和组合数据的工具,它可以用来遍历集合、执行过滤、映射和折叠等操作。例如,`for (x ) yield computation(x)`,这会创建一个新的列表,其中包含满足条件的...

    scala-in-action_ZH_CN:《Scala in Action》中文翻译

    ###《Scala in Action》中文翻译——个人自娱,与版权无关 目 录 第一部分: 第1章: 1.1 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 ...2.1 Scala解释器下的REPL ...2.5 For-comprehensions 2.6 Pattern matching 2.7

    scala:Scala参考(如Java开发人员所见)

    Scala的语法比Java更为简洁,如if表达式可以作为返回值,for-comprehensions用于迭代和查询。此外,还有case classes和match表达式,使得代码更接近自然语言。 8. **元编程**: Scala的反射和类型系统支持元编程...

    scala3-monads

    此外,Monad Comprehensions(也称为For Comprehensions)在Scala 3中仍然存在,它是使用`for`语法糖来构建Monad链的一种方式。 总结来说,Scala 3通过类型类、`do`表达式、`Given`和`MonadError`等新特性,使Monad...

    effectful, 在 Scala 中,类型安全effectful计算的语法.zip

    effectful, 在 Scala 中,类型安全effectful计算的语法 Effectful 如果我们想要理解所有这些结构的符号影响,也许我们应该尝试回收已经经拥有的符号。,Paterson,,,,。Effectful是一个小型的宏库,允许你以比 ...

    ScalaByExample.pdf

    《Scala By Example》是Martin Odersky所著的一本关于Scala编程语言的实践指南,旨在通过实例介绍Scala的核心概念和编程技巧。以下是该书部分章节的关键知识点总结: 1. **表达式与简单函数**: - **表达式**: ...

    Haskell、Ocaml和Python中说明的函数式编程概念、示例和模式_Haskell_Scala_下载.zip

    8. List comprehensions:这是函数式编程中处理序列的一种简洁方式,Haskell、OCaml和Python都提供了列表推导式,允许简洁地创建和过滤列表。 9. Pattern Matching:Haskell和OCaml支持模式匹配,这是一种强大的...

    essential-slick-3

    For Comprehensions 是 Scala 中的一个强大特性,可以用来简洁地组合多个查询。书中介绍了如何利用这一特性来简化查询操作。 #### 1.4.10 动作组合 除了 For Comprehensions 之外,还可以使用 Slick-3 的动作组合...

    SparkCodingChallenge

    在SparkCodingChallenge中,我们可以预见...同时,熟悉Scala语言的特性和最佳实践也非常重要,例如使用Option和Try来处理可能的null值,利用for-comprehensions进行控制流,以及使用pattern matching来解构复杂类型等。

    函数式编程思维.pdf_函数式编程_函数式编程思维_

    函数式编程语言或支持函数式特性的语言,如Haskell、Lisp、Scala、F#和JavaScript(通过ES6的箭头函数和闭包),提供了丰富的工具和概念来支持这一编程范式。例如,高阶函数(接受函数作为参数或返回函数的函数)...

Global site tag (gtag.js) - Google Analytics