f# - 避免迭代的最佳方法
问题描述
我有一个字符串
testString = "Hello [1], my name is [2]"
我想替换它,所以它等于
Hello Maria, my name is My.
我有一个函数,它需要一个字符串和替换列表。然后根据需要遍历该列表替换。
let parse testString (replacements: list<string>) =
let mutable result = testString
for index = 1 to replacements.Length do
result <- result.Replace("[" + (index).ToString() + "]", replacements.[index-1])
result
parse testString ["Maria";"My"]
但是,由于我切换到 F# 的主要原因之一是避免迭代和可变性,那么解决这个问题的最佳方法是什么?
我考虑过字符串上的正则表达式替换回调或结果列表上的迭代器/映射(似乎是最好的方法)。
解决方案
以下是您可以用更惯用的 F# 解决问题的几种方法:
let testString = "Hello [1], my name is [2]"
let parse input replacements =
replacements
|> List.mapi (fun i s -> i + 1, s) //Create a tuple with the index and the string
|> List.fold (fun (result: string) (i, s) -> result.Replace($"[{i}]", s)) input //Fold iterates through the list making the replacements recursively
let parse2 input replacements =
let rec parse2' (input:string) (replacements:string list) i =
match replacements with
| [] -> input //Replacements are empty so return the input
| s :: replacements ->
// Take the head element off the list using pattern matching
// Make a recursive call after performing the replacement
parse2' (input.Replace($"[{i}]", s)) replacements (i + 1)
parse2' input replacements 1
printfn "%s" (parse testString [ "Maria"; "My" ])
printfn "%s" (parse2 testString [ "Maria"; "My" ])
请注意,您的代码没有什么特别的问题,F# 鼓励采用混合方法来解决问题。如果您限制它们的范围,可变性和“原始”迭代是没有问题的。在这种情况下,变量永远不会离开函数的范围,因此它与程序的其余部分无关。
推荐阅读
- jsf - 我的表格仅在两次单击 commandButton 后更新
- swift - Swift 以编程方式添加本地联系人容器
- c++ - 如何将整数向量转换为 2 位十六进制并按顺序添加到 c 字符串?
- javascript - HTTP 请求承诺和并发
- html - x溢出时,子div的背景不会水平填充父div
- typescript - 单身人士在自己的文件中时的问题
- javascript - 如何通过javascript在HTML表格中追加大数据而不会使浏览器崩溃
- linux - ImportError:/lib64/libc.so.6:在 RHEL 6.9(圣地亚哥)的导入 tensorflow 上找不到版本“GLIBC_2.17”
- mysql - MySQL如果用CASE语句重新评估列然后别名相同的名称,如何引用别名?
- java - 如何在实时数据库firebase中获取第一个子节点