Scala 如何过滤满足非降序且元素和为奇数的嵌套List元素
嵌套List过滤的常见错误与正确实现
你之前写法的核心问题
- 对Scala
filter方法的参数规则理解有误:filter接收的谓词函数只接收当前遍历的单个元素作为入参,你写的l.filter(_ < _)这类双下划线占位符的写法,会被编译器识别为需要两个入参的函数,根本无法正常编译;就算修正了参数数量问题,这个写法本质是在比较子列表对象本身,完全检查不到子列表内部的元素顺序。 - 两个判断条件的逻辑完全和需求错位:
- 非降序判断需要检查子列表内部相邻元素的大小关系,不能直接拿子列表对象本身做大小比较
- 元素和为奇数的判断需要先累加整个子列表的所有元素,再判断奇偶,你之前写的
_ + _ % 2 !=0就算能编译,也只是对两个元素做运算,和“求全列表总和”的需求完全不匹配
可直接运行的正确实现
我们把两个过滤条件拆开实现,逻辑更易读:
- 非降序判断:用
sliding(2)方法获取子列表中每一组相邻的两个元素,通过forall检查所有相邻组都满足「前一个元素 ≤ 后一个元素」 - 奇和判断:直接调用List自带的
sum方法求总和,再判断总和对2取余不等于0
完整代码示例:
val l = List(List(1,2,3), List(1,2,4), List(9,8,7)) val filteredResult = l.filter { subList => val isNonDecreasing = subList.sliding(2).forall { case Seq(prev, next) => prev <= next } val isSumOdd = subList.sum % 2 != 0 isNonDecreasing && isSumOdd } // 输出结果:List(List(1, 2, 4)),和预期完全一致
如果偏好链式写法,也可以拆成两次filter调用,效果完全相同:
val filteredResult = l .filter(_.sliding(2).forall { case Seq(prev, next) => prev <= next }) .filter(_.sum % 2 != 0)
注意:如果子列表长度小于2(空列表、单元素列表),
sliding(2)会返回空迭代器,forall对空集合会默认返回true,刚好符合非降序的数学定义,不会出现判断错误。
内容的提问来源于stack exchange,提问作者disshethard
相关产品推荐
相关产品推荐

