用F#实现List.scani的好方法是什么?

用F#实现List.scani的好方法是什么?,f#,F#,我遇到的情况是,我正在分析一个文件,我需要了解这两个方面: 当前线路 前一行 在上一行要求之前,我做了如下工作: myData |> List.mapi (fun i data -> parse i data) 但是现在我需要访问前一行,所以扫描是理想的选择,但是我失去了索引 因此,我需要一个List.scani函数:)它是可以用惯用的方式轻松构建的吗?这可能不是最有效的方法,但它似乎有效(我称之为scanl,因为您希望访问上一个元素或行): 用法示例: let l = [1.

我遇到的情况是,我正在分析一个文件,我需要了解这两个方面:

  • 当前线路
  • 前一行
在上一行要求之前,我做了如下工作:

myData
|> List.mapi (fun i data -> parse i data)
但是现在我需要访问前一行,所以扫描是理想的选择,但是我失去了索引


因此,我需要一个List.scani函数:)它是可以用惯用的方式轻松构建的吗?

这可能不是最有效的方法,但它似乎有效(我称之为scanl,因为您希望访问上一个元素或行):

用法示例:

let l = [1..5]

scanl (fun acc elem0 elem1 -> elem0,elem1) (0,0) l
//result: [(0, 0); (1, 1); (1, 2); (2, 3); (3, 4); (4, 5)]
通常的List.scan会给出以下信息:

List.scan (fun acc elem -> elem) 0 l
//result [0; 1; 2; 3; 4; 5]

这可能不是最有效的方法,但似乎有效(我称之为scanl,因为您希望访问前面的元素或行):

用法示例:

let l = [1..5]

scanl (fun acc elem0 elem1 -> elem0,elem1) (0,0) l
//result: [(0, 0); (1, 1); (1, 2); (2, 3); (3, 4); (4, 5)]
通常的List.scan会给出以下信息:

List.scan (fun acc elem -> elem) 0 l
//result [0; 1; 2; 3; 4; 5]

您可以如下定义scani:

let scani (f:int->'S->'T->'S) (state:'S) (list:'T list) = 
    list
    |>List.scan (fun (i,s) x -> (i+1,f i s x)) (0,state)
    |>List.map snd
创建具有原始状态的元组和使用
(0,状态)
初始化的计数器。该状态像往常一样通过文件夹函数f(现在需要一个额外的i参数)和递增1的计数器进行操作。最后,通过获取状态的第二个元素,我们将计数器从状态中移除

您可以如下使用它,其中i是索引,s是状态,x是元素

[1;2;3]
|> scani (fun i s x -> s + i*x) 0
|> should equal [0;0;2;8]

您可以如下定义scani:

let scani (f:int->'S->'T->'S) (state:'S) (list:'T list) = 
    list
    |>List.scan (fun (i,s) x -> (i+1,f i s x)) (0,state)
    |>List.map snd
创建具有原始状态的元组和使用
(0,状态)
初始化的计数器。该状态像往常一样通过文件夹函数f(现在需要一个额外的i参数)和递增1的计数器进行操作。最后,通过获取状态的第二个元素,我们将计数器从状态中移除

您可以如下使用它,其中i是索引,s是状态,x是元素

[1;2;3]
|> scani (fun i s x -> s + i*x) 0
|> should equal [0;0;2;8]

你考虑过使用
List.index
List.pairwise
组合吗?@HenrikHansen,不,我没想到你考虑过使用
List.index
List.pairwise
组合吗?@HenrikHansen,不,我没想到