• Scala---For语句段


    For语句段
    语法:
    Expr1 ::= „for‟ („(‟ Enumerators „)‟ | „{‟ Enumerators
    „}‟) {nl} [„yield‟] Expr
    Enumerators ::= Generator {semi Enumerator}
    Enumerator ::= Generator
    | Guard
    | „val‟ Pattern1 „=‟ Expr
    Generator ::= Pattern1 „<-‟ Expr [Guard]
    Guard ::= „if‟ PostfixExpr
    for语句段for (enums) yield e对于由枚举器enums产生的每一个绑定求值表达式e。

    一个枚举器序列总是由一个产生器開始。然后可跟其它产生器,值定义,或守卫。一个产生器 p <- e从一个与模式p匹配的表达式e产生绑定。值定义val p = e将值名称p(或模式p中的数个名称)绑定到表达式e的求值结果上。守卫if e包括一个布尔表达式。限制了枚举出来的绑定。产生器和守卫的精确含义通过翻译为四个方法的调用来定义:map filter flatMap和foreach。这些方法能够针对不同的携带类型具有不同的实现。
    翻译框架例如以下。在第一步里,每一个产生器p <- e,对于e的类型被替换为例如以下形式。p不是不可反驳的(§8.1):
    p <- e.filter { case p => true; case _ => false }
    然后。下面规则将反复应用。直到全部的语句段都消耗完成。
     for语句段 for (p <- e) yield e‟被翻译为e.map { case p => e‟ }
     for语句段 for (p <- e) e‟ 被翻译为e.foreach { case p => e‟ }
     for语句段 for (p <- e; p‟ <- e‟ ...) yield e‟‟, 这里...是一个产生器或守卫序列(可能为空)。该语句段翻译为 e.flatMap { case p => for(p‟ <- e‟ ...) yield e‟‟ }
     for语句段 for (p <- e; p‟ <- e‟ ...) e‟‟
    这里... 是一个产生器或守卫序列(可能为空),该语句段翻译为 e.foreach { case p => for (p‟ <- e‟ ...) e‟‟ }
     后跟守卫if g的产生器p <- e翻译为单个产生器p <- e.filter((x1,...,xn) => g),这里x1,...,xn是p的自由变量。
     后跟值定义val p‟ = e‟的产生器 p <- e翻译为下面值对产生器,这里的x和x‟是新名称: val (p, p‟) <- for (x@p <- e) yield { val x‟@p‟ = e‟; (x, x‟) }
    演示样例6.19.1 下面代码产生1到n-1间全部和为素数的数值对
    for { i <- 1 until n
    j <- 1 until i
    if isPrime(i+j)
    } yield (i, j)
    该for语句段翻译为:
    (1 until n)
    .flatMap {
    case i => (1 until i)
    .filter { j => isPrime(i+j) }
    .map { case j => (i, j) }
    演示样例6.19.2 for语句段能够用来简明地描写叙述向量和矩阵算法。比方下面就是一个函数来计算给定矩阵的转置:
    def transpose[A](xss: Array[Array[A]]) = {
    for (i <- Array.range(0, xss(0).length)) yield
    for (xs <- xss) yield xs(i)
    }
    下面是一个函数,用来计算两个向量的无向量积:
    def scalprod(xs: Array[Double], ys: Array[Double]) = {
    var acc = 0.0
    for ((x, y) <- xs zip ys) acc = acc + x * y
    acc
    }
    最后。这是一个求两个矩阵的积的函数。

    能够与演示样例 6.15.1中的常见版本号做一个比較
    def matmul(xss: Array[Array[Double]], yss: Array[Array[Double]] = {
    val ysst = transpose(yss)
    for (xs <- xss) yield
    for (yst <- ysst) yield
    scalprod(xs, yst)
    }

    以上代码使用了类scala.Array中已有定义的成员map, flatMap, filter和foreach。

    很多其它精彩内容请关注:http://bbs.superwu.cn

    关注超人学院微信二维码:

    关注超人学院java免费学习交流群:

  • 相关阅读:
    bzoj3676 [Apio2014]回文串
    bzoj4199 [Noi2015]品酒大会
    bzoj3171 [Tjoi2013]循环格
    bzoj4709 [Jsoi2011]柠檬
    bzoj2668 [cqoi2012]交换棋子
    bzoj1458 士兵占领
    25号搜索的一些例子,。。Oil Deposits&&Red and Black&&Knight Moves&&Catch That Cow&&Tempter of the Bone
    第一次超水(我错了,有难度的)的组队赛!!!The Coco-Cola Store &&Multiple of 17&& Box Game
    博弈 7月24号:HDU 2176(Nim博弈)
    2013年7月23号:大数的加与乘I-number&&Power of Cryptography
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/5119075.html
Copyright © 2020-2023  润新知