如何解决Take while running total 小于 value
我试图生成一个偶数列表,而列表中项目的总和小于给定的数字。 例如,如果阈值 k 为 20,则预期输出为 [0;2;4;6;8]
let listofEvennumbeRSSmallerThanTwenty =
Seq.unfold (fun x -> Some(x,x + 1)) 0 // natural numbers
|> Seq.filter (fun x -> x % 2 = 0) // even numbers
|> Seq.takeWhile (fun x -> x <= 20)
|> List.ofSeq
(我知道我可以将展开和过滤器组合到 Some(x,x + 2) ,但此任务用于教育目的)
我设法创建了一个运行总数小于阈值的不同列表:
let runningTotal =
listofEvennumbeRSSmallerThanTwenty
|> Seq.scan (+) 0
|> Seq.filter (fun x -> x < 20)
|> List.ofSeq
但为了做到这一点,我在 listofEvennumbeRSSmallerThanTwenty 中设置了阈值(这比所需的项目多得多)并且我丢失了初始序列。我也确实尝试过使用可变值找到它,但并不真正喜欢那条路线。
解决方法
这是一个我认为非常优雅的解决方案(虽然不是最有效的):
let evens = Seq.initInfinite (fun i -> 2 * i)
Seq.initInfinite (fun i -> Seq.take i evens)
|> Seq.takeWhile (fun seq ->
Seq.sum seq <= 20)
|> Seq.last
|> List.ofSeq
,
您可以创建一个小的谓词函数来封装可变和。
let sumLessThan threshold =
let mutable sum = 0
fun x ->
sum <- sum + x
sum < threshold
使用非常简单,可以应用于任何序列
Seq.initInfinite ((*) 2) |> Seq.takeWhile (sumLessThan 20)
封装后使用可变状态没有什么不好的(检查Seq模块中可变变量的用法)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。