文档章节

内建控制结构之for表达式

柳哥
 柳哥
发布于 2014/06/07 12:33
字数 1569
阅读 72
收藏 1

#程序员薪资揭榜#你做程序员几年了?月薪多少?发量还在么?>>>

Scala的for表达式是枚举操作的“瑞士军刀”,它可以让你用不同的方式把若干简单的成分组合起来以表达各种各样的枚举。


枚举集合类
For能做的最简单的事情就是把集合中所有元素都枚举一遍。如例:

package scalaTest
object Test4 {
    def main(args:Array[String]) {
        val fileHere = (new java.io.File(".")).listFiles
        for(file <- fileHere) println(file)
    }
}

通过使用被称为发生器的语法“file <- filesHere”,我们遍历了filesHere的元素。每一次枚举,名为file的新的val就被元素值初始化。编译器能够推断出file的类型是File,因为fileHere是Array[File]。对于每一次枚举,for表达式的函数体println(file),将被执行一次。由于File的toString方法生成文件或目录的名称,因此当前目录的所有文件和目录的名称都会被打印出来。
For表达式语法对任何种类的集合类都有效,而不只是数组。如例,你可以使用类似“1 to 5”这样的语法很方便地创建Range(这个后面再讲解),然后用for做枚举。

package scalaTest
object Test4 {
    def main(args:Array[String]) {
        for(i <- 1 to 9) println("Iteration " + i)
    }
}

如果不想包括被枚举的Range上边界,还可以用until替代to,如例:

package scalaTest
object Test4 {
    def main(args:Array[String]) {
        for(i <- 1 until 9) println("Iteration " + i)     //注意这里
    }
}


过滤
有时候你并不想枚举集合的全部元素,而只是想过滤出某个子集。这可以通过在for表达式的括号中添加过滤器(if子句)实现。如例:

package scalaTest
object Test4 {
    def main(args:Array[String]) {
        for(i <- 1 until 9 if i % 2 == 0) println("Iteration " + i)
    }
}

或者也可以采用如下写法:

package scalaTest
object Test4 {
    def main(args:Array[String]) {
        for(i <- 1 until 9)
            if(i % 2 == 0) println("Iteration " + i)
    }
}

这段代码对于指令式背景的程序员来说看上去更熟悉一些。然而指令式的格式只是可选的实现方法之一。For表达式之所以被称为“表达式”是因为它能产生有意义的值,其类型取决于for表达式<-子句的集合。需要的话,你可以包含更多的过滤器。只要不断添加if子句即可。如例:

package scalaTest
object Test4 {
    def main(args:Array[String]){
        for(
            i <- 1 until 9
            if i % 2 == 0;    //注意这里要分号
            if i % 4 == 0
        ) println("Iteration " + i)
    }
}

注意:如果在发生器中加入超过一个过滤器,if子句必须用分号分隔注:在scala2.10.7版本下好像不用分号了!!!)。


嵌套枚举
如果加入多个 <-子句,你就得到了嵌套的“循环”。如下例:

package scalaTest
object Test4 {
    def main(args:Array[String]){
        val arr = Array(Array(1,2,3,4,5),Array(11,12,13,14,15))
        for(
            ar <- arr
            if ar(0) > 10;    //注意这里要加分号
            a <- ar
            if a % 2 == 0 
        )println("Iteration " + a)
    }
}

注意嵌套枚举之间也必须用分号分隔。如果愿意的话,你可以使用花括号代替小括号包裹发生器和过滤器你用花括号的好处是可以省略使用小括号时必须加的分号(当然不去掉分号也是可以的);如例:

package scalaTest
object Test4 {
    def main(args:Array[String]){
        val arr = Array(Array(1,2,3,4,5),Array(11,12,13,14,15))
        for{        //注意这里,是大括号哦
            ar <- arr if ar(0) > 10
            a <- ar if a % 2 == 0
        }println("Iteration " + a)
    }
}


流间变量绑定

package scalaTest
object Test4 {
    def main(args:Array[String]){
        val arr = Array(Array("  a","b"," c "),Array("D","  E","F   "))
        for{
            ar <- arr if ar(0).trim == "a"
            a <- ar if a.trim == "c"
        }println(a.trim)
    }
}

请注意前面的代码段中重复出现了表达式a.trim,这是个不可忽略的计算,因此你或许希望只算一遍。这可以通过用等号(=)把结果绑定到新变量实现。绑定的变量被当作val引入和使用,不过不带关键字val,如例:

package scalaTest
object Test4{
    def main(args:Array[String]){
        val arr = Array(Array("a","b  ","  c  "),Array("D","  E","F   "))
        for{
            ar <- arr if ar(0).trim == "a"
            a <- ar            //注意,这里要么换行,要么加分号
            k = a.trim if k == "c"
        }println(k)
    }
}

不换行,加分号的例子:

package scalaTest
object Test4 {
    def main(args:Array[String]) {
        val arr = Array(Array(" a","b "," c "),Array("D","  E","F  "))
        for{
            ar <- arr if ar(0).trim == "a"
            a <- ar;k = a.trim if k == "c"    //这里加了分号
        }println(k)
    }
}

代码中,名为k的变量被从半路引入for表达式,并被初始化为a.trim的结果值。于是之后的for表达式在两个地方使用了新的变量,一次在if中,另一次在println中。


制造新集合
到现在为止所有的例子都只是对枚举值进行操作然后就释放,除此之外,你还可以创建一个值去记住每一次的迭代只要在for表达式之后加上关键字yield。如例:

package scalaTest
object Test4 {
    def main(args:Array[String]){
        val arr = Array(Array(" a","b "," c "),Array("D","  E","F  "))
        //注意这里
        var arr2 = for{
            ar <- arr if ar(0).trim == "a"
            a <- ar;k = a.trim if k == "c" || k == "b"
        }yield k
        for(s <- arr2) println("子集合元素: " + s)
    }
}

又例:

package scalaTest
object Test4{
    def main(args:Array[String]){
        val arr = Array(Array(" a","b "," c "),Array("D","  E","F  "))
        def fuOne(arr:Array[Array[String]]) = for{
            ar <- arr if ar(0).trim == "a"
            a <- ar;k = a.trim if k== "c" || k == "b"
        }yield k
        for(s <- funOne(arr)) println("子集合元素: " + s)
    }
}

For表达式在每次执行的时候都会产生一个新值,本例中是k。当for表达式完成的时候,结果将是包含了所有产生值的集合对象。对象的类型基于枚举子句处理的集合类型(上例中就是Array[String],这里是一维的)。
另外,请注意放置yield关键字的地方。对于for-yield表达式的语法是这样的 :for {子句} yield {循环体},如例:

package scalaTest
object Test4 {
    def main(args:Array[String]){
        val arr = Array(Array(" a","b "," c "),Array("D","  E","F  "))
        def funOne(arr:Array[Array[String]]) = for{
            ar <- arr if ar(0).trim == "a"
            a <- ar;k = a.trim if k == "c" || k == "b"
        }yield{
            println("~~~~~" + k)
            k
        }
    }
}

yield在整个循环体之后。即使循环体是被花括号包围的代码块,也一定要把yield放在左花括号之后
截止目前,你已经看过了scalafor表达式的所有主要特征,不过这一段过得实在是快了一些,我们后面会再详细介绍。

© 著作权归作者所有

柳哥
粉丝 206
博文 405
码字总数 347782
作品 0
杭州
技术主管
私信 提问
加载中

评论(0)

Bash Shell内建命令和保留字

文章来源: https://blog.csdn.net/liuligui5200/article/details/52493100 有需要请查看原文, 我只是拷贝 命令 含义 ! 保留字,逻辑非 : 不做任何事,只做参数展开 . 读取文件并在shell中执行...

osc_51w4wn2j
2019/01/30
6
0
Programming In Scala笔记-第七章、Scala中的控制结构

  所谓的内建控制结构是指编程语言中可以使用的一些代码控制语法,如Scala中的if, while, for, try, match, 以及函数调用等。需要注意的是,Scala几乎所有的内建控制结构都会返回一个值,这...

dabokele
03/31
0
0
Python提供的一些相当实用而灵活的通用数据结构

本章介绍Python的基本数据类型和数据结构,它们按照如下方式组织。 基本数据类型 3.1节介绍整数、浮点数和字符串等基本数据类型。 基本数据结构 3.2节介绍Python的基本数据结构(例如List对象...

人邮异步社区
04/15
0
0
freemarker语法介绍及其入门

FreeMarker标签使用 一、FreeMarker模板文件主要有4个部分组成 1、文本,直接输出的部分 2、注释,即<#--...-->格式不会输出 3、插值(Interpolation):即${..}或者#{..}格式的部分,将使用数...

wersdffg
2014/09/30
1.3K
0
Python核心编程第二版(中文).pdf 目录整理

转:https://www.cnblogs.com/yufeihlf/p/5709832.html python核心编程目录 Chapter1:欢迎来到python世界!-页码:7 1.1什么是python 1.2起源 :罗萨姆1989底创建python 1.3特点 1.3.1高级 ...

osc_a9b6fe4t
2019/06/21
2
0

没有更多内容

加载失败,请刷新页面

加载更多

Python笔记:记pandas中几个好用的函数

pandas是python数据分析常用的库之一!从数据加载到预处理,从数据分析到可视化,pandas提供了一站式服务。而以下这几个聚合统计函数,更是好用! 本文主要讲解pandas中的7个聚合统计相关函数...

tengyulong
28分钟前
17
0
使用“ let”和“ var”有什么区别? - What's the difference between using “let” and “var”?

问题: ECMAScript 6 introduced the let statement . ECMAScript 6引入了let语句 。 I've heard it that it's described as a "local" variable, but I'm still not quite sure how it beh......

javail
今天
17
0
如何将文件重置或还原到特定版本? - How can I reset or revert a file to a specific revision?

问题: I have made some changes to a file which has been committed a few times as part of a group of files, but now want to reset/revert the changes on it back to a previous ver......

fyin1314
今天
24
0
OSChina 周五乱弹 —— 头发和不要头发,你总要选一个

Osc乱弹歌单(2020)请戳(这里) 【今日歌曲】 @薛定谔的兄弟 :分享洛神有语创建的歌单「我喜欢的音乐」: 《雾 缀じた街 ふたつのかげ》- Porkkana 手机党少年们想听歌,请使劲儿戳(这里)...

小小编辑
今天
49
0
一道 算法题 引发的 ‘xx现场’

请 熟悉的语言 去 验证 在输入框中输入的是否是一个正确的网址 初次读题萌新有点 不知所措的样子一查 MDN 吓一跳 ----- 一个不怎么熟悉的方法跳出眼边URL() 构造函数返回一个新创建的 ...

酒窝yun过去了
今天
19
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部