我有一个字符串,里面有一些标记,如下所示:
"There are two things to be replaced. {Thing1} and {Thing2}"
我想用不同的值替换每个令牌,因此最终结果如下所示:
"There are two things to be replaced. Don and Jon"
我创建了一个链接字符串的函数。
let doReplacement (message:string) (thing1:string) (thing2:string) =
message.Replace("{Thing1}", thing1).Replace("{Thing2}", thing2)
问题是当我链接.替换时,值必须保持在同一行上。 这样做不起作用:
let doReplacement (message:string) (thing1:string) (thing2:string) =
message
.Replace("{Thing1}", thing1)
.Replace("{Thing2}", thing2)
为了允许我做一个多线链,我想到了这样的事情:
message
|> replaceString "{Thing1}" thing1
|> replaceString "{Thing2}" thing2
具有这样的支持功能:
let replaceString (message:string) (oldValue:string) (newValue:string) =
message.Replace(oldValue, newValue)
但是,这行不通。 有没有其他方法可以处理这个问题?
如果您缩进方法调用,它将编译:
let doReplacement (message:string) (thing1:string) (thing2:string) =
message
.Replace("{Thing1}", thing1)
.Replace("{Thing2}", thing2)
这是我在 C# 中经常看到的一种风格,对我来说似乎很合乎逻辑。
通过使用|>
将管道值发送到最右侧的未绑定参数(由|>
管道传输的值发送到thing2(。 通过反转参数的顺序,它按预期工作。
let replaceString (oldValue:string) (newValue:string) (message:string) =
message.Replace(oldValue, newValue)
let message = "There are two things to be replaced. {Thing1} and {Thing2}"
let thing1 = "Don"
let thing2 = "Jon"
message
|> replaceString "{Thing1}" thing1
|> replaceString "{Thing2}" thing2
|> printfn "%s"
您也可以使用折叠来完成此操作(尽管需要在列表/映射中输入。如果你有一致的替换,你会更有用,这可能不适合你(
let replacements =
[ "{thing1}", "Don"
"{thing2}", "Jon" ]
let replaceString (input: string) : string =
replacements
|> List.fold (fun acc (oldText, newText) -> acc.Replace(oldText, newText)) input
或者更一般的情况,输入替换作为参数(这次是地图(
let replaceString (replaceMap: Map<string, string>) (input: string) : string =
replaceMap
|> Map.fold (fun acc oldText newText -> acc.Replace(oldText, newText)) input