如何以函数式方式实现按条件拆分List的grouping函数
用函数式编程实现
grouping函数 嘿,这个需求在函数式编程里很常见,我们可以用纯函数式的方式(无可变状态、依赖折叠操作)来实现这个grouping函数,完全贴合你的要求:
函数实现
我们用foldLeft——函数式编程中处理列表聚合的经典工具——来实现,全程不使用可变变量,完全依赖不可变数据的逐步构建:
def grouping[T](xs: List[T], rule: T => Boolean): Tuple2[List[T], List[T]] = xs.foldLeft((List.empty[T], List.empty[T])) { case ((matches, nonMatches), elem) => // 根据规则将当前元素分到对应的列表分支 if (rule(elem)) (elem :: matches, nonMatches) else (matches, elem :: nonMatches) } match { // 因为foldLeft遍历元素时是往列表头部追加,最后反转恢复原列表的元素顺序 case (matched, nonMatched) => (matched.reverse, nonMatched.reverse) }
调用验证
按照你给出的调用方式测试:
// 测试整数分组 println(grouping(List(1, 2, 100, 3, 4, 501, 12), (x: Int) => x >= 100)) // 测试字符分组 println(grouping(List('A', 'C', 'Z', 'T', 'O', 'P', 'N', 'M', 'Y'), (x: Char) => x >= 'J'))
输出结果和你预期的完全一致:
(List(100, 501), List(1, 2, 3, 4, 12)) (List(Z, T, O, P, N, M, Y), List(A, C))
额外小提示
其实Scala标准库已经内置了这个功能,直接调用xs.partition(rule)就能得到一模一样的二元组结果。不过手动用foldLeft实现的方式,能更直观地理解函数式编程中“通过折叠操作聚合不可变数据”的核心逻辑~
内容的提问来源于stack exchange,提问作者Anna
相关产品推荐
相关产品推荐

