在Scala中使用span函数拆分Map
在Scala中使用
span拆分你的Map 嘿,我来帮你搞定这个问题!首先得先搞清楚span函数到底是干啥的——它会把你的集合拆成两个部分:
- 第一部分是从集合开头开始连续满足你指定条件的所有元素
- 第二部分是剩下的所有元素(从第一个不满足条件的元素开始,后面的全算)
注意哦:Scala 2.13及以后的不可变Map是保留插入顺序的,所以拆分的顺序会和你添加元素的顺序一致;如果是更早的版本,Map是无序的,那span的结果可能不符合预期,这点要留意~
针对你的Map类型的具体用法
你的Map类型是Map[Int, Option[(String, List[Int])]],我们分两种常见场景来演示:
场景1:拆分出所有Some值的连续条目和剩下的None条目
首先先定义好你的完整Map:
val myMap: 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)
然后用span,通过模式匹配判断value是否为Some:
val (entriesWithSome, entriesWithNone) = myMap.span { case (_, value) => value.isDefined }
运行后你会得到:
entriesWithSome:Map(500 -> Some((A,List(1, 2, 3))), 400 -> Some((B,List(9, 8, 7))))entriesWithNone:Map(300 -> None, 200 -> None)
场景2:根据Some内部的内容拆分
如果你想更精准地筛选,比如只拆分出Some里字符串为"A"的连续条目,那可以这样写:
val (entriesWithA, otherEntries) = myMap.span { case (_, Some(("A", _))) => true // 匹配Some里第一个元素是"A"的条目 case _ => false }
这时候entriesWithA里就只有500 -> Some((A,List(1, 2, 3)))这一条,剩下的所有条目都在otherEntries里。
注意:span和partition的区别
别搞混哦!span是遇到第一个不满足条件的元素就停止拆分,而partition会遍历整个集合,把所有满足和不满足条件的元素分别归到两个部分。举个例子:
// 故意把None插在Some中间 val mixedMap = Map(500 -> Some(("A", List(1,2,3)))) + (300 -> None) + (400 -> Some(("B", List(9,8,7)))) val (firstPart, secondPart) = mixedMap.span(_._2.isDefined)
这时候firstPart只有500的条目(因为下一个是None,触发停止),而secondPart包含300和400的条目——哪怕400的value是Some,也会被归到第二部分,这就是span的特性!
内容的提问来源于stack exchange,提问作者Nirmalya
相关产品推荐
相关产品推荐

