文档章节

Scala 的 yield 例子 (for 循环和 yield 的例子)

月下独酌100
 月下独酌100
发布于 2016/04/06 15:10
字数 936
阅读 48
收藏 1

我看了《Programming in Scala》一书,仍然对 Scala yield 关键字的理解不甚清楚。起初我以为 Scala yield 的与 Ruby 的 yield 是一样,Ruby 中 yield 是被传入代码块的占位符。Scala 中的 yield 关键字好像总是在 for 循环中用的. 下面一些例子可以帮助你更好的理解 yield 关键字。下面是摘自 《Programming in Scala》关于 yield 的解释:


For each iteration of your for loop, yield generates a value which will be remembered. It's like the for loop has a buffer you can't see, and for each iteration of your for loop, another item is added to that buffer. When your for loop finishes running, it will return this collection of all the yielded values. The type of the collection that is returned is the same type that you were iterating over, so a Map yields a Map, a List yields a List, and so on.

Also, note that the initial collection is not changed; the for/yield construct creates a new collection according to the algorithm you specify.

上面那段话的意义就是,for 循环中的 yield 会把当前的元素记下来,保存在集合中,循环结束后将返回该集合。Scala 中 for 循环是有返回值的。如果被循环的是 Map,返回的就是  Map,被循环的是 List,返回的就是 List,以此类推。

基于上面的信息,来看几个例子:

scala> for (i <- 1 to 5 ) yield i
res 10 : scala.collection.immutable.IndexedSeq[Int] = Vector( 1 , 2 , 3 , 4 , 5 )

前面的例子都不算什么,还只是个开始. 接下来, 对我们初始集合的每个元素做一次翻倍:

scala> for (i <- 1 to 5 ) yield i * 2
res 11 : scala.collection.immutable.IndexedSeq[Int] = Vector( 2 , 4 , 6 , 8 , 10 )

这里是 for/yield 循环的求模操作:

scala> for (i <- 1 to 5 ) yield i % 2
res 12 : scala.collection.immutable.IndexedSeq[Int] = Vector( 1 , 0 , 1 , 0 , 1 )

Scala 数组上的 for 循环 yield 的例子

之前提到过 for 循环 yield 会构造并返回与给定集合相同类型的集合. 为此, 我们来看看以下用 Scala 数组上的例子. 注意把 yield(我们可以把 yield 用作一个动词) 出来的集合类型与前面的几个例子对比:

scala> val a = Array( 1 , 2 , 3 , 4 , 5 )
a : Array[Int] = Array( 1 , 2 , 3 , 4 , 5 )
 
scala> for (e <- a) yield e
res 5 : Array[Int] = Array( 1 , 2 , 3 , 4 , 5 )
 
scala> for (e <- a) yield e * 2
res 6 : Array[Int] = Array( 2 , 4 , 6 , 8 , 10 )
 
scala> for (e <- a) yield e % 2
res 7 : Array[Int] = Array( 1 , 0 , 1 , 0 , 1 )

正如你所见, 例子中被 yield 的是 Array[Int], 而更早的例子中返回的类型是 IndexedSeq[Int].

for 循环, yield, 和守卫( guards) (for loop 'if' conditions)

假如你熟悉了 Scala 复杂的语法, 你就会知道可以在 for 循环结构中加上 'if' 表达式. 它们作为测试用,通常被认为是一个守卫,你可以把它们与 yield 语法联合起来用。参见::

scala> val a = Array( 1 , 2 , 3 , 4 , 5 )
a : Array[Int] = Array( 1 , 2 , 3 , 4 , 5 )
 
scala> for (e <- a if e > 2 ) yield e
res 1 : Array[Int] = Array( 3 , 4 , 5 )

如上, 加上了 "if e > 2" 作为守卫条件用以限制得到了只包含了三个元素的数组.

Scala for 循环和 yield 的例子 - 总结

如果你熟悉 Scala 的 loop 结构, 就会知道在 for 后的圆括号中还可以许更多的事情. 你可以加入 "if" 表达式,或别的语句, 比如下面的例子,可以组合多个 if 语句:

def scalaFiles =
   for {
     file <- filesHere
     if file.isFile
     if file.getName.endsWith( ".scala" )
   } yield file

yield 关键字的简短总结:

  • 针对每一次 for 循环的迭代, yield 会产生一个值,被循环记录下来 (内部实现上,像是一个缓冲区).

  • 当循环结束后, 会返回所有 yield 的值组成的集合.

  • 返回集合的类型与被遍历的集合类型是一致的.

希望上面的例子结诸位有所帮助. 



本文转载自:http://unmi.cc/scala-yield-samples-for-loop/

月下独酌100
粉丝 26
博文 220
码字总数 56475
作品 0
浦东
高级程序员
私信 提问
Scala 的 yield 例子 (for 循环和 yield 的例子)

我看了《Programming in Scala》一书,仍然对 Scala yield 关键字的理解不甚清楚。起初我以为 Scala yield 的与 Ruby 的 yield 是一样,Ruby 中 yield 是被传入代码块的占位符。Scala 中的 ...

Zero零_度
2016/08/16
16
0
Scala 的学习笔记系列(持续更新中)

最近学习 Scala,因它是灵活的函数式编程,还有就是能为 PlayFramework 2.0 服务,看的是 《Programming in Scala》 那本书,并记下自己认为值得记录的东西,列举 Scala 用元组/列表类型实现...

YanbinQ
2012/10/26
507
1
第十章 Scala 容器基础(十):使用for循环来遍历一个集合

Problem 我想使用for循环来遍历容器的所有元素,或者通过for yield来创建一个新的集合。 Solution 你可以使用for循环遍历所有的Traversable类型(基本上所有的sequency都可以): scala> val f...

阿拉德大陆的魔法师
2016/04/10
455
0
Scala 学习一

1.IDEA新建scala相关文档 https://www.jetbrains.com/help/idea/2016.3/creating-and-running-your-scala-application.html 2.Scanla 变量 变量的类型在变量名之后等号之前声明。定义变量的类...

Zhao-Qian
2016/12/16
43
0
【scala初学】scala 控制 for while match if

上一章我们共同研究了for循环以及变种。这章我们围绕比较常用的几个其他控制语句学习。 首先,对for进行补充, For-Comprehensions 格式: for (s ) yield e 举例: var range = 0.until(10...

yjplxq
2014/05/17
0
0

没有更多内容

加载失败,请刷新页面

加载更多

《Designing.Data-Intensive.Applications》笔记 四

第九章 一致性与共识 分布式系统最重要的的抽象之一是共识(consensus):让所有的节点对某件事达成一致。 最终一致性(eventual consistency)只提供较弱的保证,需要探索更高的一致性保证(stro...

丰田破产标志
今天
6
0
docker 使用mysql

1, 进入容器 比如 myslq1 里面进行操作 docker exec -it mysql1 /bin/bash 2. 退出 容器 交互: exit 3. mysql 启动在容器里面,并且 可以本地连接mysql docker run --name mysql1 --env MY...

之渊
今天
7
0
python数据结构

1、字符串及其方法(案例来自Python-100-Days) def main(): str1 = 'hello, world!' # 通过len函数计算字符串的长度 print(len(str1)) # 13 # 获得字符串首字母大写的...

huijue
今天
5
0
OSChina 周日乱弹 —— 我,小小编辑,食人族酋长

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @宇辰OSC :分享娃娃的单曲《飘洋过海来看你》: #今日歌曲推荐# 《飘洋过海来看你》- 娃娃 手机党少年们想听歌,请使劲儿戳(这里) @宇辰OSC...

小小编辑
今天
1K
11
MongoDB系列-- SpringBoot 中对 MongoDB 的 基本操作

SpringBoot 中对 MongoDB 的 基本操作 Database 库的创建 首先 在MongoDB 操作客户端 Robo 3T 中 创建数据库: 增加用户User: 创建 Collections 集合(类似mysql 中的 表): 后面我们大部分都...

TcWong
今天
40
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部