【问题标题】:Sublists of list in F#F#中列表的子列表
【发布时间】:2016-05-15 03:28:34
【问题描述】:

如何获取子列表

[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]]

谢谢。

【问题讨论】:

  • 不知道是否有惯用的方式,但你的方式很好(只需添加一个地图来反转列表)-顺便说一句:它被称为heads ;)
  • 子列表要多得多;)
  • 我说的是List.scan (fun acc elem -> elem::acc) [] [1;2;3;4;5] |> List.map List.rev |> List.tail
  • 哎呀我的坏...它可能被称为 inits 而不是 *heads*

标签: list f# linked-list


【解决方案1】:

这是另一个:

let f n = List.init n (fun i -> [1..(i + 1)])

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

【讨论】:

    【解决方案2】:

    把我的扔到堆上,这可能是对傻瓜回答的改进:

    let inits list =
        list |> List.mapi (fun i _ -> List.take (i + 1) list)
    

    mapi 是一个有用的函数:你提供一个函数来获取每个索引和项目。

    【讨论】:

    • 我在List 模块中找不到take 方法
    • 它只存在于 F# 4.0 及更高版本中。您可以使用以下命令将其添加到列表模块:module List = let take n l = Seq.take n l |> Seq.toList。我只把它放在一行,因为这是一条评论。
    【解决方案3】:

    你的实现很好。这是我的替代方案:

    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)
    

    【讨论】:

    • 虽然OP的版本要好很多
    • @Carsten,你为什么这么说?对我来说,这更简单。它对输入列表进行了两次迭代,但每个输出子列表只创建一次,因为不需要反向。
    • 它也会调用take n-times
    • 这只是一个口味问题 - 对我来说,如果性能相关(使用 snoc-lists),OP 的答案更接近于你会做的方式 - 如果你可以忽略错误的顺序(并且忽略/不要使用List.map List.rev),这只是更好的选择
    猜你喜欢
    • 2021-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多