如何按值过滤[String, Seq[Int]]类型Map并提取指定子序列
问题背景
需要对类型为Map[String, Seq[Int]]的集合按value做过滤转换,初始测试数据:
val data: Map[String, Seq[Int]] = Map("a" -> Seq(1,2,3,4,5,6), "b" -> Seq(2,3,4,5,6,7), "c" -> Seq(3,4,5,6,7,8), "d"->Seq(1))
处理规则:
- 若value的Seq中存在指定连续子序列,就把该子序列作为新的value保留条目
- 若不存在对应子序列,直接删除整个条目
以查找子序列Seq(4,5)为例,期望输出:
Map("a" -> Seq(4,5), "b" -> Seq(4,5), "c" -> Seq(4,5))
原有代码的问题
你写的两段代码逻辑完全一致,存在两个核心错误:
- 方法选型错误:Map的
filter方法仅能判断整个键值对是否保留,无法修改value内容,实现不了"提取子序列替换原value"的需求 - 匹配逻辑错误:你在遍历Seq的单个Int类型元素时,判断元素是否等于二元组
(4,5),两者类型根本不匹配,判断结果永远为false,最终会过滤掉所有条目返回空Map。
正确实现
用collect搭配滑动窗口方法sliding即可实现需求,代码如下:
// 定义要查找的目标子序列 val target = Seq(4, 5) val res = data.collect { case (key, seq) if seq.sliding(target.length).contains(target) => key -> target }
逻辑说明
sliding(窗口长度)会将原序列按固定长度切分出所有连续子序列,例如Seq(1,2,3,4,5,6).sliding(2)会依次生成Seq(1,2)、Seq(2,3)、Seq(3,4)、Seq(4,5)、Seq(5,6)- 守卫条件判断当前序列是否包含目标连续子序列,不满足的条目会被
collect自动过滤 - 满足条件的条目直接将value替换为目标子序列即可,运行结果和预期完全一致。
如果需求不需要匹配连续子序列,只要序列中同时包含4和5两个元素,直接把判断条件换成seq.contains(4) && seq.contains(5)就行。
内容的提问来源于stack exchange,提问作者kneelb4darth
相关产品推荐
相关产品推荐

