您的位置:首页 > 产品设计 > UI/UE

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

2017-01-16 15:53 218 查看

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

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

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

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

再说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), <
4000
span class="hljs-keyword">Range(20, 21, 22))


通过序列解析或者说for推导式,我们可以方便的处理序列,得到新的序列,有兴趣的读者可以尝试如果用Java来实现上述例子需要多少代码,就可以更好的理解Scala的便捷了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐