f# 运行总计序列

发布于 2024-10-27 11:50:56 字数 101 浏览 2 评论 0原文

好吧,这看起来应该很容易,但我就是不明白。如果我有一个数字序列,如何生成由运行总计组成的新序列?例如,对于序列 [1;2;3;4],我想将其映射到 [1;3;6;10]。以适当的功能方式。

Ok, this looks like it should be easy, but I'm just not getting it. If I have a sequence of numbers, how do I generate a new sequence made up of the running totals? eg for a sequence [1;2;3;4], I want to map it to [1;3;6;10]. In a suitably functional way.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

楠木可依 2024-11-03 11:50:56

使用 List.scan

let runningTotal = List.scan (+) 0 >> List.tail

[1; 2; 3; 4]
|> runningTotal
|> printfn "%A"

基于Seq.scan的实现:

let runningTotal seq' = (Seq.head seq', Seq.skip 1 seq') ||> Seq.scan (+)

{ 1..4 }
|> runningTotal
|> printfn "%A"

Use List.scan:

let runningTotal = List.scan (+) 0 >> List.tail

[1; 2; 3; 4]
|> runningTotal
|> printfn "%A"

Seq.scan-based implementation:

let runningTotal seq' = (Seq.head seq', Seq.skip 1 seq') ||> Seq.scan (+)

{ 1..4 }
|> runningTotal
|> printfn "%A"
怼怹恏 2024-11-03 11:50:56

另一种使用 Seq.scan 的变体(Seq.skip 1 去掉了前导零):

> {1..4} |> Seq.scan (+) 0 |> Seq.skip 1;;
val it : seq<int> = seq [1; 3; 6; 10]

Another variation using Seq.scan (Seq.skip 1 gets rid of the leading zero):

> {1..4} |> Seq.scan (+) 0 |> Seq.skip 1;;
val it : seq<int> = seq [1; 3; 6; 10]
烏雲後面有陽光 2024-11-03 11:50:56
> Seq.scan (fun acc n -> acc + n) 0 [1;2;3;4];;
val it : seq<int> = seq [0; 1; 3; 6; ...]

使用列表:

> [1;2;3;4] |> List.scan (fun acc n -> acc + n) 0 |> List.tail;;
val it : int list = [1; 3; 6; 10]

编辑:序列的另一种方式:

let sum s = seq {
    let x = ref 0
    for i in s do
        x := !x + i
        yield !x
}

是的,有一个可变变量,但我发现它更具可读性(如果你想去掉前导 0)。

> Seq.scan (fun acc n -> acc + n) 0 [1;2;3;4];;
val it : seq<int> = seq [0; 1; 3; 6; ...]

With lists:

> [1;2;3;4] |> List.scan (fun acc n -> acc + n) 0 |> List.tail;;
val it : int list = [1; 3; 6; 10]

Edit: Another way with sequences:

let sum s = seq {
    let x = ref 0
    for i in s do
        x := !x + i
        yield !x
}

Yes, there's a mutable variable, but I find it more readable (if you want to get rid of the leading 0).

七分※倦醒 2024-11-03 11:50:56

我认为值得分享如何使用 记录类型< /a> 如果这也是您来这里寻找的东西。

下面是一个虚构的示例,使用跑步者绕跑道跑一圈来演示这一概念。

type Split = double
type Lap = { Num : int; Split : Split }
type RunnerLap = { Lap : Lap; TotalTime : double }

let lap1 = { Num = 1; Split = 1.23 } 
let lap2 = { Num = 2; Split = 1.13 } 
let lap3 = { Num = 3; Split = 1.03 } 
let laps = [lap1;lap2;lap3]

let runnerLapsAccumulator =  
  Seq.scan 
    (fun rl l -> { rl with Lap = l; TotalTime = rl.TotalTime + l.Split }) // acumulator
    { Lap = { Num = 0; Split = 0.0 }; TotalTime = 0.0 } // initial state

let runnerLaps = laps |> runnerLapsAccumulator
printfn "%A" runnerLaps

Figured it was worthwhile to share how to do this with Record Types in case that's also what you came here looking for.

Below is a fictitious example demonstrating the concept using runner laps around a track.

type Split = double
type Lap = { Num : int; Split : Split }
type RunnerLap = { Lap : Lap; TotalTime : double }

let lap1 = { Num = 1; Split = 1.23 } 
let lap2 = { Num = 2; Split = 1.13 } 
let lap3 = { Num = 3; Split = 1.03 } 
let laps = [lap1;lap2;lap3]

let runnerLapsAccumulator =  
  Seq.scan 
    (fun rl l -> { rl with Lap = l; TotalTime = rl.TotalTime + l.Split }) // acumulator
    { Lap = { Num = 0; Split = 0.0 }; TotalTime = 0.0 } // initial state

let runnerLaps = laps |> runnerLapsAccumulator
printfn "%A" runnerLaps
月野兔 2024-11-03 11:50:56

不确定这是最好的方法,但它应该可以解决问题

  let input = [1; 2; 3; 4]
  let runningTotal = 
    (input, 0) 
    |> Seq.unfold (fun (list, total) ->
      match list with
      | [] -> 
        None
      | h::t -> 
        let total = total + h
        total, (t, total) |> Some)
    |> List.ofSeq

Not sure this is the best way but it should do the trick

  let input = [1; 2; 3; 4]
  let runningTotal = 
    (input, 0) 
    |> Seq.unfold (fun (list, total) ->
      match list with
      | [] -> 
        None
      | h::t -> 
        let total = total + h
        total, (t, total) |> Some)
    |> List.ofSeq
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文