f# - 如何在 F# 中对顺序值进行分组

标签 f#

让我们考虑以下排序数据:

[1; 2; 3; 5; 6; 20; 21; 22; 23]

我想得到:

[ [1; 2; 3]; [5; 6]; [20; 21; 22; 23] ]

实现此目标的最佳方法是什么? (列表最多 1000 个条目)。

最佳答案

这里的版本可能更加地道,至少对我而言,更具可读性。它仅依赖于 List 模块中的标准函数 foldBack 并完全避免了可变性。

let group ls =
    (ls, [])
    ||> List.foldBack (fun l s ->
        match s with 
        | [] | [[]] -> [[l]]
        | (n::res)::ns ->
            if n = l+1
            then (l::n::res)::ns
            else [l]::(n::res)::ns)

它也可能被重构为一个更通用的函数

let chunkBy cond ls =
    (ls, [])
    ||> List.foldBack (fun l s ->
        match s with 
        | [] | [[]] -> [[l]]
        | (n::res)::ns ->
            if cond l n
            then (l::n::res)::ns
            else [l]::(n::res)::ns)

let group = chunkBy (fun prev next -> prev + 1 = next)

请注意,这利用了仅在列表上实现的缺点运算符 ::。 cons 运算符将一个项目添加到列表中,这就是该函数使用 foldBack 的原因。

关于f# - 如何在 F# 中对顺序值进行分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68968531/

相关文章:

f# p/invoke on GetClientRect with pointers works 但不适用于 OutAttribute

f# - FSharp.Data 缺少方法异常

f# - 如何禁用 Lint 工具上的行数警告?

f# - 我的 rec 函数是尾递归的吗?

.net - F# 将 TextBlock 向上转换为 UIElement

F#接口(interface)继承失败,由于单元

documentation - F# Powerpack 文档

types - 如何在 F# 中定义两个相互依赖的类型?

f# - f# 中的赋值运算符

F# 参数传递