我找不到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
答案 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)