gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-01 11:08:09 24 4
gpt4 key购买 nike

我正在尝试 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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com