使用span函数在Scala中平分Map

时间:2018-04-03 07:30:42

标签: scala

我有一个[Int,Option [/ *某种类型我正在使用* /]的地图,因此:

scala> val t1: Map[Int,Option[(String,List[Int])]] = Map(500->Some("A",List(1,2,3)))
t1: Map[Int,Option[(String, List[Int])]] = Map(500 -> Some((A,List(1, 2, 3))))

scala> t1 + (400 -> Some("B",List(9,8,7))) + (300 -> None) + (200 -> None)
res6: scala.collection.immutable.Map[Int,Option[(String, List[Int])]] = Map(500 -> Some((A,List(1, 2, 3))), 400 -> Some((B,List(9, 8, 7))), 300 -> None, 200 -> None)

现在,我正在尝试切割成两个地图,一个具有所有空值 - 来自同名键/值 - 而另一个没有它们,因此:

res6.span(e => e._2.isEmpty)
res7: (scala.collection.immutable.Map[Int,Option[(String, List[Int])]], scala.collection.immutable.Map[Int,Option[(String, List[Int])]]) = (Map(),Map(500 -> Some((A,List(1, 2, 3))), 400 -> Some((B,List(9, 8, 7))), 300 -> None, 200 -> None))

我无法理解为什么我在左边得到一张空地图,而< K,>双人幸福地坐在右边的地图上。他们本应该在左边的地图上,或者我期待。

我遗失的显而易见的事情是什么?

2 个答案:

答案 0 :(得分:4)

您应该使用partition代替span

  

注意:c span p相当于(但可能更有效)(c takeWhile p,c dropWhile p),前提是谓词p的评估不会引起任何副作用。

因此,如果不满足条件,span将停止扫描。

例如,

scala> val l = List(1, 9, 8, 0)
scala> l.span(e => e < 2)
res7: (List[Int], List[Int]) = (List(1),List(9, 8, 0))
scala> l.partition(e => e < 2)
res8: (List[Int], List[Int]) = (List(1, 0),List(9, 8))

请注意,实际上对于span,它可能会针对不同的运行返回不同的结果,除非订购了基础集合类型。

在您的情况下,map 中的第一个元素可能不会 None。 (Map未订购)

答案 1 :(得分:-1)

根据定义,当您使用span时,我们会获得与原始集合类型相同的Tuple2个序列,其中一个包含true个值和其他false

 def span(p: A => Boolean): (Repr, Repr) = 

在你的情况下

res6.span(e => e._2.isEmpty)

因此,在您的情况下,您有Tuple2的emptynon-empty元素。

如果您希望获得non-empty值,请使用_2作为

val nonEmptyValue = res6.span(e => e._2.isEmpty)._2