Scala之集合上常见的函数式风格的操作汇总

推荐:博主历时三年倾注大量心血创作的《大数据平台架构与原型实现:数据中台建设实战》一书已由知名IT图书品牌电子工业出版社博文视点出版发行,真诚推荐给每一位读者!点击《重磅推荐:建大数据平台太难了!给我发个工程原型吧!》了解图书详情,扫码进入京东手机购书页面!

在这里插入图片描述

 

 

目录

正文

函数式编程对集合操作有一些通行的“叫法”,或者更像是一些“俚语”,它们的含义清晰明确,但是很难顾名思义,比如常见的“filter”,“map”,“flatMap”,“redue"等等。本文会把一些主要“俚语”详细地解释一下,同时给出一些参考示例。

#“过滤”相关的操作

##filter

###解释

设定一个判定结果为布尔型的过滤条件,应用到集合的每一个元素上,返回的是集合里所有满足条件的元素构成的一个子集。

###示例

scala> List.range(1, 11).filter (_ % 3 == 0)
res1: List[Int] = List(3, 6, 9)
scala> List("the", "quick", "brown", "fox", "jumped","over", "the", "lazy", "dog").filter(_.length == 3)
res2: List[String] = List(the, fox, the, dog)

##partition

###解释

filter类型操作的一个变种,同样是设定一个判定结果为布尔型的过滤条件,应用到集合的每一个元素上,返回的是二个元素的Tuple, 第一个元素是所有满足条件的元素构成一个集合,第二个元素是所有不满足条件的元素构成一个集合。

###示例

scala> List.range(1, 11).partition(_ % 3 == 0)
res3: (List[Int], List[Int]) = (List(3, 6, 9),List(1, 2, 4, 5, 7, 8, 10))

##find

###解释

filter类型操作的一个变种,同样是设定一个判定结果为布尔型的过滤条件,返回集合中满足条件的第一个元素。

###示例

scala> List.range(1, 11).find(_ % 3 == 0)
res4: Option[Int] = Some(3)

##takeWhile

###解释

filter类型操作的一个变种,同样是设定一个判定结果为布尔型的过滤条件,从集合的第一个元素开始,逐一判定元素是否符合条件,在遇到第一个不符合条件的元素后随即结束过滤,返回的结果就是集合中前N个连续满足条件的元素。

###示例

scala> List(1, 2, 3, -4, 5, 6, 7, 8, 9, 10) takeWhile (_ > 0)
res5: List[Int] = List(1, 2, 3)

#“映射”相关的操作

##map

###解释

设定一个针对元素的“转换”操作,应用到集合的每一个元素上,返回的结果是每个元素被转换之后的新值组成的新集合。新的集合与旧集合大小一样,但元素都是更新的,甚至类型也会发生变化。

###示例

scala> List(1, 2, 3, 4, 5) map (_ + 1)
res6: List[Int] = List(2, 3, 4, 5, 6)

scala> List("the", "quick", "brown", "fox", "jumped","over", "the", "lazy", "dog").map(_.length)
res7: List[Int] = List(3, 5, 5, 3, 6, 4, 3, 4, 3)

##flatMap

###解释

对于嵌套的集合(即集合中的元素还是集合),如果我们希望把每一个嵌套的子集“转换”成一个新的子集,这时候就应该使用flatMap。

flatMap,不单单应用于集合,它代表着一种很普遍的操作:对于某种嵌套的数据结构,如果它的某个操作会把它的嵌套元素转化或产生出新嵌套元素,则最终产生的将是一个“二维”的数据结构,也就是嵌套元素本身也是一个嵌套元素,这通常会让这个产出的结果很不好用,一个必备的工作就是把这个二维”的数据结构“压平”,重新拼接成一个一维的结构,这正是flatMap要做的事情。所以除了集合,Future也有这个方法,它就是在你使用map去转换它的underlying时返回的又恰巧是一个Future,那么这时你可以使用flatMap进行扁平化处理,得到的还是一个Future,而不是Future嵌套着Future。

###示例

scala> List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9)) flatMap (_.toList)
res2: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9)

scala> List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9)) flatMap (_.reverse)
res3: List[Int] = List(3, 2, 1, 6, 5, 4, 9, 8, 7)

要特别注意的是flatMap使用的函数参数接收的是一个集合,返回的也是一个集合(GenTraversableOnce),你不能将一个集合元素“转换”成单一的值,比如,你不能这样做:

###示例

scala> List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9)) flatMap (_ + 1)
<console>:12: error: type mismatch;
 found   : Int(1)
 required: String
       List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9)) flatMap (_ + 1)
                                                                      ^

如果你想针对嵌套集合中的每个元素进行装换得到一个统一的集合,你可以这做做:

scala> List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9)) flatMap (_.map(_+1))
res10: List[Int] = List(2, 3, 4, 5, 6, 7, 8, 9, 10)

下面是一个flatMap更加直观的例子:

#“扁平化”相关的操作

##flatten

###解释

在函数式编程里经常会出现嵌套的集合,我们需要频繁地把这种嵌套的结构”压“成”扁平“的单一集合,这个动作在函数式编程里叫"flatten"。即:将所有嵌套的集合的元素一一取出逐一放置到一个集合中。

###示例

scala> List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9)).flatten
res12: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9)
scala> List("the", "quick", "brown", "fox", "jumped","over", "the", "lazy", "dog").flatten
res13: List[Char] = List(t, h, e, q, u, i, c, k, b, r, o, w, n, f, o, x, j, u, m, p, e, d, o, v, e, r, t, h, e, l, a, z, y, d, o, g)

#“折叠”相关的操作

##reduceLeft

###解释

如果我们把集合看成是一张纸条,每一小段代表一个元素,那么reduceLeft就将这张纸条从左向右"折叠",最前面的两个元素会首先“重叠”在一起,这时会使用传给reduceLeft的参数函数进行计算,返回的结果就像是已经折叠在一起的两段纸条,它们已经是一个叠加的状态了,所以它,也就是上次重叠的结果会继续做为一个单一的值和下一个元素继续“叠加”,直到折叠到集合的最后一个元素。

###示例

scala> List.range(1, 10).reduceLeft(_+_)
res0: Int = 45

##reduceRight

###解释

同理,reduceRight就将这张纸条从右向左"折叠"。要留心reduceRight的地方时:它的操作方向是从右到左,但是参数的顺序却并不是,而是依然第一参数是左边的元素,第二参数是右边的元素。我们可以通过一个示例来验证:

###示例

List.range(1, 10) reduceRight(_ - _)
// 8 - 9 = -1
// 7 - (-1) = 8
// 6 - 8 = -2
// 5 - (-2) = 7
// 4 - 7 = -3
// 3 - (-3) = 6
// 2 - 6 = -4
// 1 - (-4) = 5
// result: 5

##foldLeft

###解释

与reduceLeft极为相似,只是它开始操作的第一个元素是以参数的形式传入的,而不是集合的第一个元素。

###示例

scala> List.range(1, 10).foldLeft(1)(_+_)
res1: Int = 46

##foldRight

###解释

与reduceRight极为相似,只是它开始操作的第一个元素是以参数的形式传入的,而不是集合的最后一个元素。

###示例

scala> List.range(1, 10).foldRight(5)(_ - _)
res8: Int = 0

本文原文出处: http://blog.csdn.net/bluishglc/article/details/53320654 转载请注明出处。

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Laurence 

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值