scala-06Map、Tuple、Zip实战解析

本文介绍了Scala中的基本数据结构如List、Set、Option等,并通过实例演示了map、foreach、filter等函数组合器的应用技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MapTupleZip实战解析

基本数据结构

 

List

1

2

scala> val numbers = List(1234)

numbers: List[Int] = List(1234)

Set

集合中没有重复元素

1

2

scala> Set(112)

res0: scala.collection.immutable.Set[Int] = Set(12)

 

Option

Option是一个包含或者不包含某些事物的容器。

Option的基本接口类似于:

1

2

3

4

5

trait Option[T] {

  def isDefined: Boolean

  def get: T

  def getOrElse(t: T): T

}

Option本身是泛型的,它有两个子类:Some[T]和None

我们来看一个Option的示例: Map.get使用Option来作为它的返回类型。Option的作用是告诉你这个方法可能不会返回你请求的值。

1

2

3

4

5

6

7

8

scala> val numbers = Map(1 -> "one"2 -> "two")

numbers: scala.collection.immutable.Map[Int,String] = Map((1,one), (2,two))

 

scala> numbers.get(2)

res0: Option[java.lang.String] = Some(two)

 

scala> numbers.get(3)

res1: Option[java.lang.String] = None

现在,我们要的数据存在于这个Option里。那么我们该怎么处理它呢?

一个比较直观的方法就是根据isDefined方法的返回结果作出不同的处理。

1

2

3

4

5

6

7

//如果这个值存在的话,那么我们把它乘以2,否则返回0。

 

val result = if (res1.isDefined) {

  res1.get * 2

else {

  0

}

 

不过,我们更加建议你使用getOrElse或者模式匹配来处理这个结构。

getOrElse让你可以很方便地定义一个默认值。

1

val result = res1.getOrElse(0) * 2

模式匹配可以很好地和Option进行配合使用。

val result = res1 match { case Some(n) => n * 2 case None => 0 }

参考 《Effective Scala》中关于 Options的内容。

函数组合器

List(1,2,3) map squared会在列表的每个元素上分别应用squared函数,并且返回一个新的列表,可能是List(1,4,9)。我们把类似于map这样的操作称为组合器。(如果你需要一个更好的定义,你或许会喜欢Stackoverflow上的关于组合器的解释

map

在列表中的每个元素上计算一个函数,并且返回一个包含相同数目元素的列表。

1

2

scala> numbers.map((i: Int) => i * 2)

res0: List[Int] = List(2468)

或者传入一个部分计算的函数

1

2

3

4

5

scala> def timesTwo(i: Int): Int = i * 2

timesTwo: (i: Int)Int

 

scala> numbers.map(timesTwo _)

res0: List[Int] = List(2468)

foreach

foreach和map相似,只不过它没有返回值,foreach只要是为了对参数进行作用。

1

scala> numbers.foreach((i: Int) => i * 2)

没有返回值。

你可以尝试把返回值放在一个变量里,不过它的类型应该是Unit(或者是void)

1

2

scala> val doubled = numbers.foreach((i: Int) => i * 2)

doubled: Unit = ()

filter

移除任何使得传入的函数返回false的元素。返回Boolean类型的函数一般都称为断言函数。

1

2

scala> numbers.filter((i: Int) => i % 2 == 0)

res0: List[Int] = List(24)

 

1

2

3

4

5

scala> def isEven(i: Int): Boolean = i % 2 == 0

isEven: (i: Int)Boolean

 

scala> numbers.filter(isEven _)

res2: List[Int] = List(24)

zip

zip把两个列表的元素合成一个由元素对组成的列表里。

1

2

scala> List(123).zip(List("a""b""c"))

res0: List[(Int, String)] = List((1,a), (2,b), (3,c))

partition

partition根据断言函数的返回值对列表进行拆分。

1

2

3

scala> val numbers = List(12345678910)

scala> numbers.partition(_ %2 == 0)

res0: (List[Int], List[Int]) = (List(246810),List(13579))

find

find返回集合里第一个匹配断言函数的元素

1

2

scala> numbers.find((i: Int) => i > 5)

res0: Option[Int] = Some(6)

drop & dropWhile

drop丢弃前i个元素

1

2

scala> numbers.drop(5)

res0: List[Int] = List(678910)

dropWhile移除前几个匹配断言函数的元素。例如,如果我们从numbers列表里dropWhile奇数的话,1会被移除(3则不会,因为它被2所“保护”)。

1

2

scala> numbers.dropWhile(_ % 2 != 0)

res0: List[Int] = List(2345678910)

foldLeft

1

2

scala> numbers.foldLeft(0)((m: Int, n: Int) => m + n)

res0: Int = 55

0是起始值(注意numbers是一个List[Int]),m是累加值。

更加直观的来看:

1

2

3

4

5

6

7

8

9

10

11

12

scala> numbers.foldLeft(0) { (m: Int, n: Int) => println("m: " + m + " n: " + n); m + n }

m: 0 n: 1

m: 1 n: 2

m: 3 n: 3

m: 6 n: 4

m: 10 n: 5

m: 15 n: 6

m: 21 n: 7

m: 28 n: 8

m: 36 n: 9

m: 45 n: 10

res0: Int = 55

foldRight

这个和foldLeft相似,只不过是方向相反。

1

2

3

4

5

6

7

8

9

10

11

12

scala> numbers.foldRight(0) { (m: Int, n: Int) => println("m: " + m + " n: " + n); m + n }

m: 10 n: 0

m: 9 n: 10

m: 8 n: 19

m: 7 n: 27

m: 6 n: 34

m: 5 n: 40

m: 4 n: 45

m: 3 n: 49

m: 2 n: 52

m: 1 n: 54

res0: Int = 55

flatten

flatten可以把嵌套的结构展开。

1

2

scala> List(List(12), List(34)).flatten

res0: List[Int] = List(1234)

flaoMap

flatMap是一个常用的combinator,它结合了map和flatten的功能。flatMap接收一个可以处理嵌套列表的函数,然后把返回结果连接起来。

1

2

3

4

5

scala> val nestedNumbers = List(List(12), List(34))

nestedNumbers: List[List[Int]] = List(List(12), List(34))

 

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

res0: List[Int] = List(2468)

可以把它当作map和flatten两者的缩写:

1

2

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

res1: List[Int] = List(2468)

这个调用map和flatten的示例是这些函数的类“组合器”特点的展示。

See Also Effective Scala has opinions about flatMap.

flaoMap

flatMap是一个常用的combinator,它结合了map和flatten的功能。flatMap接收一个可以处理嵌套列表的函数,然后把返回结果连接起来。

1

2

3

4

5

scala> val nestedNumbers = List(List(12), List(34))

nestedNumbers: List[List[Int]] = List(List(12), List(34))

 

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

res0: List[Int] = List(2468)

可以把它当作map和flatten两者的缩写:

1

2

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

res1: List[Int] = List(2468)

这个调用map和flatten的示例是这些函数的类“组合器”特点的展示。

See Also Effective Scala has opinions about flatMap.

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值