F#函数将n维列表转换为一维列表

标签 f#

我正在尝试 F# 中的一些小任务来帮助掌握这门语言。

我想编写一个函数,它接受一个 n 维列表并返回一个包含每个维度的所有元素的一维列表。

例如,如果输入是以下 3 维列表:[[[1;2];[3;4]];[[5;6];[7;8]]],输出将是:[1;2;3;4;5;6;7;8]

对于 2 维 -> 1 维,函数非常简单:

let coalesce list= List.collect(fun item -> item) list

这是我尝试将其推广到 n 维:

let rec coalesce (list, dimension) = 
    if dimension = 1 then list 
    else coalesce (List.collect(fun item -> item) list, dimension - 1)

当我尝试编译时出现以下错误:

错误 FS0001:类型不匹配。期待一个
'列表列表
但给了一个
'一个列表
当统一 ''a' 和 ''a list' 时,结果类型将是无限的

问题在这里:

List.collect(fun item -> item) list

我的想法显然有问题。编写此类函数的正确方法是什么?

最佳答案

此操作类型不正确,但这里有一个适用于 IEnumerable 的示例s 并返回 list<obj> :

let rec coalesce(list:System.Collections.IEnumerable, dim) =
    [
        if dim=1 then for x in list do yield x
        else
            for x in list do
                match x with
                | :? System.Collections.IEnumerable as s ->
                    yield! coalesce(s, dim-1)
                | _ -> failwith "bad shape"
    ]
printfn "%A" (coalesce([1;2], 1))
printfn "%A" (coalesce([[1;2];[3;4]], 2))
printfn "%A" (coalesce([[[1;2];[3;4]];[[5;6];[7]]], 3))

你也可以这样写

let rec flatten(list:System.Collections.IEnumerable) =
    [for x in list do
        match x with
        | :? System.Collections.IEnumerable as s -> yield! flatten(s)
        | _ -> yield x
    ]

哪个更通用,例如

let weird : obj list = [[box [1;2]; box 3]; 4; [box [5;6]; box 7]]
printfn "%A" (flatten weird)

编辑

@Jon Harrop 提出了另一种策略——为嵌套列表创建一个新类型:

type NestedListElement<'T> = //'
    | L of NestedListElement<'T> list //'
    | V of 'T //'

let rec flatten nlist = 
    [for x in nlist do 
        match x with 
        | L l -> yield! flatten l
        | V v -> yield v
    ] 

let nested = [L[L[V 1;V 2]; V 3]; V 4; L[L[V 5;V 6]; V 7]] 
printfn "%A" (flatten nested) 

关于F#函数将n维列表转换为一维列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3207522/

相关文章:

c# - C# 中的委托(delegate)和 F# 中作为第一类值的函数有什么区别?

xamarin - 函数式编程和依赖倒置 : how to abstract storage?

f# - 如何获取列表减少抛出算术溢出

.net - 使用 F# 控制台 onExit 事件

f# - 如何实现Task.Map

f# - 一个很好的 F# 代码库,可供学习

带有自定义运算符的 F# 嵌套计算表达式

xml - F# 中的模式匹配 XML

c# - Azure移动服务: Serialization of Tables

azure - 使用 F# 在 Azure 辅助角色中托管 SignalR 时出现 FileLoadException