我如何在F#中使用String.iter

时间:2018-07-20 22:01:17

标签: string loops f#

我找不到String.iter的任何示例,所以我一直在研究Seq.iter和Array.iter的示例,并尝试将其应用于字符串中的chars,但我做对了。有人可以给我一个关于如何使用String.iter的例子。我需要对字符串中的每个字符执行功能。

这是我以前的工作,但是我知道可以对其进行改进并使其更高效,我不想为了将其循环而必须将字符串转换为字符列表。

let chars = [ 'a'; 'b'; 'c' ]
let mutable result = 0

for c in chars do
    match c with
    | 'a' -> (result <- result + 1)
    | 'b' -> (result <- result + 2)
    | 'c' -> (result <- result + 3)
    | _ -> printfn "test"

printfn "result of %A is %d" chars result

System.Console.ReadKey() |> ignore

1 个答案:

答案 0 :(得分:3)

首先,F#的类型为string(这是.NET类型),与char list(它是功能性的F#字符列表)的类型不同。在您的示例中,您正在创建一个字符列表,因此可以使用List模块中的函数来对其进行最佳处理。

关于迭代-在您的情况下,您正在累积一些状态,因此iter不是您需要的操作(iter用于对每个元素执行某些命令性操作)。

要解决您的特定问题,最好的选择是使用List.sumBy

let result = chars |> List.sumBy (fun c ->
    match c with
    | 'a' -> 1
    | 'b' -> 2
    | 'c' -> 3
    | _ -> 
        printfn "test"
        0 )

sumBy函数将为每个元素返回的数字相加,因此您只需要返回1、2或3。在其余情况下,我们打印(具有相同的副作用)并返回0,因为只是想保持相同的金额。

更一般而言,您可以使用List.fold,这样您可以在遍历列表时累积结果:

let result = chars |> List.fold (fun result c ->
    match c with
    | 'a' -> result + 1
    | 'b' -> result + 2
    | 'c' -> result + 3
    | _ -> 
        printfn "test"
        result ) 0

在所有这些中,您可以将List.替换为Seq.,因为Seq.中的函数可以按任何序列(列表,数组,字符串等)使用。这可能会慢一些,但这通常不是问题。 String模块的功能较少,如果您将输入定义为"abc"而不是['a';'b';'c']

,则可以使用它

编辑:要回答评论中的问题,如果您可以直接在字符串上使用Seq.sumBy,并且可以使用int将字符转换为数字代码,因此您可以使用它来消除模式匹配(这以相同的方式处理所有字符,您可能要先使用Seq.filter来过滤掉无效字符,具体取决于您要实现的逻辑):

let str = "abc"
let result = str |> Seq.sumBy (fun c -> (int c) - 96)