在F#中链接string.replace

时间:2018-06-18 10:55:37

标签: f#

我有一个包含一些令牌的字符串,如下所示:

"There are two things to be replaced.  {Thing1} and {Thing2}"

我想用不同的值替换每个标记,因此最终结果如下所示:

"There are two things to be replaced.  Don and Jon"

我创建了一个像这样链接String.Replace的函数

let doReplacement (message:string) (thing1:string) (thing2:string) =
    message.Replace("{Thing1}", thing1).Replace("{Thing2}", thing2)

问题是,当我链接.Replace时,值必须保持在同一行。这样做不起作用:

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)

然而,这不起作用。还有另一种方法可以解决这个问题吗?

3 个答案:

答案 0 :(得分:6)

通过使用|>,管道值将发送到最右边的未绑定参数(由|>传送的值将发送到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"

答案 1 :(得分:6)

如果你缩进方法调用,它会编译:

let doReplacement (message:string) (thing1:string) (thing2:string) =
    message
        .Replace("{Thing1}", thing1)
        .Replace("{Thing2}", thing2)

这是我在C#中经常看到的一种风格,对我来说似乎很合乎逻辑。

答案 2 :(得分:0)

您也可以折叠来完成此操作(尽管需要在列表/地图中输入。如果您要进行一致的替换,则可能会有用,

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