Scala学习笔记之序列解析(Sequence Comprehensions)

来源:互联网 发布:陈奕迅热门歌曲知乎 编辑:程序博客网 时间:2024/06/04 19:05

Scala学习笔记之序列解析(Sequence Comprehensions)

序列解析又称for推导式,表达式如下:

for (enumerators) yield e,即由关键字for开头,后接圆括号或者花括号,中间是计数器,后接关键字yield,再后接表达式e,最终返回表达式计算结果组成的序列。

先解释计数器,在Scala中就是循环条件和过滤条件,所有支持mapfilterWithflatMap操作的数据类型都可以用在这里。

再说yield后面的表达式,是对前面计数器生成的每个绑定值进行的计算,最终将每个计算结果组成序列返回。

先举个简单例子:

for (i <- List.range(0, 20) if i % 2 == 0) yield i

按照之前的解释,先看计数器,i <- List.range(0, 20)遍历0到20,if i % 2 == 0过滤只要偶数,yield i不作其他计算,直接返回前面计算出来的偶数,所以最终输出如下:

res2: List[Int] = List(0, 2, 4, 6, 8, 10, 12, 14, 16, 18)

在来个稍微复杂一点的例子:

for (i <- 0 until 20; j <- i until 20 if i + j == 32) yield (i, j)

其实也没复杂多少,只是把循环条件多加了一条,在0到20(不含20)的循环中,再从中间值i到20循环,生成的中间值i,j以元组形式返回,所以最终结果如下:

res4: scala.collection.immutable.IndexedSeq[(Int, Int)] = Vector((13,19), (14,18), (15,17), (16,16))

接下来,再加一点复杂性:

for {i <- Range(0, 20)     j <- Range(21, 30)       if i > 14       if j < 24       isOdd = (n:Int) => n % 2 == 1        if isOdd(i)       if isOdd(j)  } yield {    Range(i + 1, j)  }

在循环中定义了一个函数isOdd用来判断是否奇数,用每个符合条件的元素重新构建区间Range,最终返回一个Range构成的序列,输出如下:

res7: scala.collection.immutable.IndexedSeq[scala.collection.immutable.Range] = Vector(Range(16, 17, 18, 19, 20), Range(16, 17, 18, 19, 20, 21, 22), Range(18, 19, 20), Range(18, 19, 20, 21, 22), Range(20), Range(20, 21, 22))

通过序列解析或者说for推导式,我们可以方便的处理序列,得到新的序列,有兴趣的读者可以尝试如果用Java来实现上述例子需要多少代码,就可以更好的理解Scala的便捷了。

0 0
原创粉丝点击