Scala片段3:列表以及Map,flatmap,zip和reduce

如果不深入探讨Map,flatMap,zip和reduce函数的细节,就无法真正谈论scala。 使用这些功能,很容易处理列表的内容并使用Option对象。 请注意,在此站点上您可以找到更多的摘要:

  1. Scala片段1:可折叠
  2. Scala片段2:列出符号魔术
  3. Scala片段3:列表以及Map,flatmap,zip和reduce

让我们从map选项开始。 使用map选项,我们将函数应用于列表的每个元素,并将其作为新列表返回。

我们可以使用它来乘以列表中的每个值:

scala> list1
res3: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
 
scala> list1.map(x=>x*x)
res4: List[Int] = List(0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100)

您应用于列表的某些功能可能会产生Option元素。 以以下功能为例:

scala> val evenify = (x:Int) => if (x % 2 == 0) Some(x) else None
evenify: Int => Option[Int] = <function1>
 
scala> list1.map(evenify)
res6: List[Option[Int]] = List(Some(0), None, Some(2), None, Some(4), None, Some(6), None, Some(8), None, Some(10))

在这种情况下,问题是我们通常对列表中的None结果不那么感兴趣。 但是,我们如何轻松地将它们释放呢? 为此,我们可以使用flatMap。 使用flatMap,我们可以处理序列列表。 我们将提供的函数应用于列表中每个序列的每个元素,并返回一个包含原始列表中每个序列的元素的列表。 一个例子更容易理解:

scala> val list3 = 10 to 20 toList
list3: List[Int] = List(10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
 
scala> val list2 = 1 to 10 toList
list2: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
 
scala> val list4 = List(list2, list3)
list4: List[List[Int]] = List(List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), List(10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20))
 
scala> list4.flatMap(x=>x.map(y=>y*2))
res2: List[Int] = List(2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40)

如您所见,我们有两个列表。 在此列表中,我们称为flatMap函数。 flatMap分别处理两个条目中的每个条目。 在每个单独的列表上,我们调用map函数来复制每个条目。 最终结果是一个列表,其中包含所有展平到单个列表的条目。

现在,让我们回顾一下我们之前看到的evenify函数以及我们拥有的Option元素列表。

scala> val list1 = 1 to 10 toList
list1: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
 
scala> list1.map(evenify)
res3: List[Option[Int]] = List(None, Some(2), None, Some(4), None, Some(6), None, Some(8), None, Some(10))
 
scala> val list2 = list1.map(evenify)
list2: List[Option[Int]] = List(None, Some(2), None, Some(4), None, Some(6), None, Some(8), None, Some(10))
 
scala> list2.flatMap(x => x)
res6: List[Int] = List(2, 4, 6, 8, 10)

容易吧。 当然,我们也可以写成一行。

scala> list1.flatMap(x=>evenify(x))
res14: List[Int] = List(2, 4, 6, 8, 10)

如您所见,并不是那么困难。 现在,让我们看看您可以在列表上使用的其他两个功能。 第一个是zip。 顾名思义,此功能可以将两个列表合并在一起。

scala> val list = "Hello.World".toCharArray
list: Array[Char] = Array(H, e, l, l, o, ., W, o, r, l, d)
 
scala> val list1 = 1 to 20 toList
list1: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
 
scala> list.zip(list1)
res30: Array[(Char, Int)] = Array((H,1), (e,2), (l,3), (l,4), (o,5), (.,6), (W,7), (o,8), (r,9), (l,10), (d,11))
 
scala> list1.zip(list)
res31: List[(Int, Char)] = List((1,H), (2,e), (3,l), (4,l), (5,o), (6,.), (7,W), (8,o), (9,r), (10,l), (11,d))

一旦一个列表到达末尾,压缩功能就会停止。 我们还有一个zipAll函数,该函数还处理较大列表中剩余的元素:

scala> list.zipAll(list1,'a','1')
res33: Array[(Char, AnyVal)] = Array((H,1), (e,2), (l,3), (l,4), (o,5), (.,6), (W,7), (o,8), (r,9), (l,10), (d,11), (a,12), (a,13), (a,14), (a,15), (a,16), (a,17), (a,18), (a,19), (a,20))

如果带有字符的列表已用尽,则如果整数列表已用尽,我们将放置字母“ a”,我们将放置1。我们将探索最后一个zip函数,即zipWithIndex。 再次,这个名字几乎概括了将会发生的事情。 将添加一个索引元素:

scala> list.zipWithIndex
res36: Array[(Char, Int)] = Array((H,0), (e,1), (l,2), (l,3), (o,4), (.,5), (W,6), (o,7), (r,8), (l,9), (d,10))

因此,最后探讨的功能是:减少。 使用reduce,我们处理列表中的所有元素并返回单个值。 使用reduceLeft和reduceRight我们可以强制处理值的方向(使用reduce不能保证):

scala> list1
res51: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
 
scala> val sum = (x:Int, y:Int) => {println(x,y) ; x + y}
sum: (Int, Int) => Int = <function2>
 
scala> list1.reduce(sum)
(1,2)
(3,3)
(6,4)
(10,5)
(15,6)
(21,7)
(28,8)
(36,9)
(45,10)
(55,11)
(66,12)
(78,13)
(91,14)
(105,15)
(120,16)
(136,17)
(153,18)
(171,19)
(190,20)
res52: Int = 210
 
scala> list1.reduceLeft(sum)
(1,2)
(3,3)
(6,4)
(10,5)
(15,6)
(21,7)
(28,8)
(36,9)
(45,10)
(55,11)
(66,12)
(78,13)
(91,14)
(105,15)
(120,16)
(136,17)
(153,18)
(171,19)
(190,20)
res53: Int = 210
 
scala> list1.reduceRight(sum)
(19,20)
(18,39)
(17,57)
(16,74)
(15,90)
(14,105)
(13,119)
(12,132)
(11,144)
(10,155)
(9,165)
(8,174)
(7,182)
(6,189)
(5,195)
(4,200)
(3,204)
(2,207)
(1,209)
res54: Int = 210

除了这些功能外,我们还具有reduceOption(以及reduceLeftOption和reduceRightOption变体)。 这些函数将返回Option而不是值。 这可用于安全处理空列表,这将导致无。

scala> list1.reduceRightOption(sum)
(19,20)
(18,39)
(17,57)
(16,74)
(15,90)
(14,105)
(13,119)
(12,132)
(11,144)
(10,155)
(9,165)
(8,174)
(7,182)
(6,189)
(5,195)
(4,200)
(3,204)
(2,207)
(1,209)
res65: Option[Int] = Some(210)
 
scala> val list3 = List()
list3: List[Nothing] = List()
 
scala> list3.reduceRightOption(sum)
res67: Option[Int] = None

该代码段足够使用,并且现在还可以浏览List / Collections API。 在下一个代码段中,我们将介绍一些Scalaz的东西,因为即使该库有点复杂,它也提供了一些非常好的功能。

翻译自: https://www.javacodegeeks.com/2014/12/scala-snippets-3-lists-together-with-map-flatmap-zip-and-reduce.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值