F#中的列表子列表

4
如何获取子列表
[1]; [1; 2]; [1; 2; 3]; ...; [1; 2; 3; ...; n]

从列表中

[1; 2; 3; ...; n]

通过最通俗易懂的方式?我能做的就是:
List.scan (fun acc elem -> elem::acc) [] [1;2;3;4;5]
> val it : int list list =
    [[]; [1]; [2; 1]; [3; 2; 1]; [4; 3; 2; 1]; [5; 4; 3; 2; 1]]

感谢您的选择。

不知道是否有惯用的方式,但你的方法很好(只需添加一个反转列表的映射)- 另外,这被称为“头部” ;) - Random Dev
有更多的子列表 ;) - Random Dev
3
我谈到的是 List.scan (fun acc elem -> elem::acc) [] [1;2;3;4;5] |> List.map List.rev |> List.tail - Random Dev
抱歉,我的错...它可能叫做inits而不是heads - Random Dev
3个回答

7

你的实现还不错。这是我的另一种选择:

let source = [1..10]

let counts = [0..source.Length] // Or start at 1 if you don't want to start with an empty list

counts |> List.map (fun count -> source |> List.take count)

2
但是楼主的版本要好得多。 - Random Dev
@Carsten,你为什么这么说?对我来说这更简单。它在输入列表上进行了两次迭代,但只创建了每个输出子列表一次,因为不需要反转。 - TheQuickBrownFox
1
它将调用 take n 次。 - Random Dev
这只是个人见解-对于我来说,如果性能很重要(使用snoc列表),OP的答案更接近你原本应该采用的方式。如果你愿意忽略错误的顺序(并且不使用 List.map List.rev),那么它就是更好的选择。 - Random Dev

4
把我的答案放在一起,这可能是对Foole的回答的完善:
let inits list =
    list |> List.mapi (fun i _ -> List.take (i + 1) list)

mapi是一个非常有用的函数:它接受一个函数作为参数,该函数将每个索引和项作为输入。


我在List模块中找不到take方法。 - Feofilakt
它只存在于 F# 4.0 及更高版本中。您可以使用以下代码将其添加到列表模块中:module List = let take n l = Seq.take n l |> Seq.toList。我将其放在一行中,因为这是一个注释。 - TheQuickBrownFox

3
这是另一个例子:
let f n = List.init n (fun i -> [1..(i + 1)])

List.init是用于初始化列表的任务。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接