文档章节

Traversing Mapping Filtering Folding Reducing

秋风醉了
 秋风醉了
发布于 2015/04/29 17:33
字数 964
阅读 39
收藏 0

Traversing Mapping Filtering Folding Reducing

Traversal

使用 foreach 遍历集合。foreach 是从特质 Iterable 混入而来的。

The signature of foreach is the following:

trait Iterable[+A]  {
 ...
 def foreach(f : (A) => Unit) :  Unit = ...
 ...
}

foreach 接收一个 函数类型的参数,所以是一个高阶函数。对于map的遍历,A 其实是一个 元组。如下代码示例,

//Traversal
List(1, 2, 3, 4, 5) foreach { i => println("Int: " + i) }

// map foreach
val stateCapitals = Map("Alabama" -> "Montgomery",
  "Alaska" -> "Juneau",
  "Wyoming" -> "Cheyenne")

stateCapitals foreach { kv => println(kv._1 + ": " + kv._2) }


Mapping

map

集合的map操作会返回和原来集合相同大小的集合。map 作用于集合中的每一个元素。

trait Iterable[+A]  {
  ...
  def map[B] (f : (A) => B) :  Iterable[B]  = ...
  ...
}

下面这个例子把原集合的key-value 中的value的类型给改变了,如下代码,

val stateCapitals = Map(
  "Alabama" -> "Montgomery",
  "Alaska" -> "Juneau",
  "Wyoming" -> "Cheyenne")
val lengths = stateCapitals map { kv => (kv._1, kv._2.length) }
println(lengths) //map操作返回的集合Map(Alabama -> 10, Alaska -> 6, Wyoming -> 8)

flatMap

结合映射[mapping]和扁平化[flattening]

flatMap的函数声明

trait Iterable[+A]  {
 ...
 def map[B]  (f : (A) => B) :  Iterable[B]  = ...
 def flatMap[B] (f : (A) => Iterable[B] ) :  Iterable[B]
 ...
}

首先假设有一个这样的情景:一个list集合,三个元素1,2,3,希望当集合元素是3 的时候,返回3.1,3.2,3.3,如果不是 3,集合元素乘以2。最终返回这样的一个集合,(2,4,3.1,3.2,3.3);

首先看一个map函数的例子,

val list = List(1, 2, 3)
val res = list.map(x => x match {
  case 3 => List(3.1, 3.2, 3.3)
  case _ => x * 2
})
println(res) //List(2, 4, List(3.1, 3.2, 3.3))

但结果不是这样的,3.1, 3.2, 3.3 是用一个集合的形式返回的。如果用flatMap会怎么样呢?

val res2 = list.flatMap(x => x match {
  case 3 => List(3.1, 3.2, 3.3)
  case _ => List(x * 2)
})

println(res2) //List(2, 4, 3.1, 3.2, 3.3)

flatMap是一种常用的组合子,结合映射[mapping]和扁平化[flattening]。 flatMap需要一个处理嵌套列表的函数,然后将结果串连起来。

val nestedNumbers = List(List(1, 2), List(3, 4))

val res5 = nestedNumbers.flatMap(x => x.map(_ * 2))

println(res5)//List(2, 4, 6, 8)

可以把它看做是“先映射后扁平化”的快捷操作:

val res6 = nestedNumbers.map((x: List[Int]) => x.map(_ * 2)).flatten

println(res6)//List(2, 4, 6, 8)

这个例子先调用map,然后可以马上调用flatten。


Filtering

filter过滤集合中的元素,

如下代码,过滤map集合中的元素

val stateCapitals = Map(
  "Alabama" -> "Montgomery",
  "Alaska" -> "Juneau",
  "Wyoming" -> "Cheyenne")

val map2 = stateCapitals.filter(kv => kv._1 startsWith ("A"))
println(map2)//Map(Alabama -> Montgomery, Alaska -> Juneau)


Reducing

reduce

使用reduce函数,对集合中的两个元素规约,直到最后一个元素,规约的顺序不是一定的。

println(List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20).reduce(
  (x: Int, y: Int) => {
    println(x, y);
    x + y
  })) //210

reduceRight 和 reduceLeft 确定了规约的方向,如下,

println(List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20).reduceRight(
  (x: Int, y: Int) => {
    println(x, y);
    x + y
  })) //210


println(List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20).reduceLeft(
  (x: Int, y: Int) => {
    println(x, y);
    x + y
  })) //210


Folding

fold

折叠,容器的折叠。

看如下例子,

val numbers = List(5, 4, 8, 6, 2)
val res90 = numbers.fold(0) { (z, i) => {
  println(z, i)
  z + i
}
}

println(res90)

运行并输出,

(0,5)

(5,4)

(9,8)

(17,6)

(23,2)

25

最后把这个集合“折叠”成25。

看一下 foldRight 和 foldLeft 的效果,

val res91 = numbers.foldRight(1) { (z, i) => {
  println(z, i)
  z + i
}
}

val res92 = numbers.foldLeft(1) { (z, i) => {
  println(z, i)
  z + i
}
}
println(res91)
println(res92)

也可以这样调用,

val res93 = numbers.foldLeft(1)((z: Int, i: Int) => {
  println(z, i)
  z + i
})

运行并输出,foldRight 从右边开始折叠,输入的初始参数为 1 ,从右边开始数,集合第一个元素是 2,相加得到 3,然后又作为下次折叠的入参,和 集合的从右边数的第二个元素相加。同理的 foldLeft。

(2,1)

(6,3)

(8,9)

(4,17)

(5,21)

26

(1,5)

(6,4)

(10,8)

(18,6)

(24,2)

26

还可以参考以下文章:

http://wanghuanming.com/2014/12/Scala-highorder-function/

http://www.ituring.com.cn/article/131442

http://www.iteblog.com/archives/1228

http://www.tuicool.com/articles/Jviyim

==========END==========

© 著作权归作者所有

共有 人打赏支持
秋风醉了
粉丝 239
博文 572
码字总数 416654
作品 0
朝阳
程序员
私信 提问
[20180112]11g关闭bloom filter.txt

[20180112]11g关闭bloom filter.txt --//11Gsql语句执行计划偶尔出现bloom filte,我上午调式生产系统sql语句,执行计划经现bloom filter,无论我使用什么提示我发现执 --//行计划都选择执行b...

lfreeali
01/12
0
0
Scala函数调用省略点号和括号

Scala函数调用省略点号和括号 省略括号 如果一个方法不用接受参数,你可以无需括号就定义它。调用者也必须不加括号地调用它。如果你加上了空括号,那么调用者可以有选择地加或者不加括号。...

秋风醉了
2015/04/29
0
0
Qt Creator 3.1.2 发布

Qt Creator 3.1.2 发布,此版本包括了 bug 修复和改进: Fix of a crash in editing with highlight definitions and indentation based folding enabled (QTCREATORBUG-12172) Fix of a GDB......

oschina
2014/06/26
3.4K
8
When.js 3.4.0 发布,增加 when.filter 过滤器

When.js 3.4.0 发布了,改进内容包括: New for filtering arrays of promises. and now provide the array index as the second param to their mapping and filtering functions. now prov......

oschina
2014/07/16
1K
0
TryjQuery:jQuery官方推出的教学视频

在今年2月15日,jQuery 官方推出“学习中心”站点后,3月底 jQuery 官方联合 code school 又推出了一个学习资源 TryjQuery,其中包括14个视频、71个交互式挑战。 3月28日我们在@程序员的那些...

xu81.com
2013/08/01
17
0

没有更多内容

加载失败,请刷新页面

加载更多

deepin中配置robot framework环境

本文永久更新地址:https://my.oschina.net/bysu/blog/2989005 【若要到岸,请摇船:开源中国 不最醉不龟归】 1.在终端中输入pip,回车,如果提示没有该命令,则先安转pip sudo apt-get inst...

不最醉不龟归
13分钟前
1
0
OSChina 周日乱弹 —— 钱不还,我就当你人不在了

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @莱布妮子 :分享Bigleaf的单曲《小鹿》 《小鹿》- Bigleaf 手机党少年们想听歌,请使劲儿戳(这里) 周日在家做什么? 做手工呀, @poorfis...

小小编辑
今天
74
3
EOS docker开发环境

使用eos docker镜像是部署本地EOS开发环境的最轻松愉快的方法。使用官方提供的eos docker镜像,你可以快速建立一个eos开发环境,可以迅速启动开发节点和钱包服务器、创建账户、编写智能合约....

汇智网教程
今天
20
0
《唐史原来超有趣》的读后感优秀范文3700字

《唐史原来超有趣》的读后感优秀范文3700字: 作者:花若离。我今天分享的内容《唐史原来超有趣》这本书的读后感,我将这本书看了一遍之后就束之高阁了,不过里面的内容一直在在脑海中回放,...

原创小博客
今天
29
0
IC-CAD Methodology知识图谱

CAD (Computer Aided Design),计算机辅助设计,指利用计算机及其图形设备帮助设计人员进行设计工作,这个定义同样可以用来近似描述IC公司CAD工程师这个岗位的工作。 早期IC公司的CAD岗位最初...

李艳青1987
今天
33
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部