F#中从字符串中删除字符

4

我对函数式编程和F#还不熟悉,虽然有很多关于如何在F#中实现字符串中删除特定字符的信息,但我发现了下面的函数,希望能得到一些帮助来理解它的确切作用:

let stripchars chars str =
  Seq.fold
    (fun (str: string) chr ->
      str.Replace(chr |> Char.ToUpper |> string, "").Replace(chr |> Char.ToLower |> string, ""))
    str chars

我使用stripchars函数,并将其调用在我定义的分割函数中,如下所示:

let split (str : string) =
    ((stripchars "?,.,!,," str).Split ' ') |> Array.toList

我现在很难理解的是,在函数stripchars中,当传递参数“chars”包含要从字符串str中删除的字符序列时,直到最后一行“str chars”才使用它。那么这怎么可能起作用呢?


3
chars 不是该函数的最后一行,它只是一个非常长的函数,因此它们在几行中分开。它实际上是 Seq.fold <some fun> str chars。由于 <some fun> 很长,为了易读性而这样写。将其放在一行上并运行以查看结果。 - Guy Coder
我现在明白了,非常感谢! - Great Cubicuboctahedron
如果您要在大字符串上使用此功能,每个要剥离的字符调用String.Replace两次将非常慢。如果您有一个非常大的输入和一个小的要剥离的字符列表,这个函数会遍历一次小的字符列表,然后多次遍历大的输入,这正好相反。当然,对于小输入字符串,除非经常调用此函数,否则并不重要。 - Joel Mueller
为什么在“?,.,!,,”中有这么多逗号?在那段代码中不需要用逗号分隔,它只是将chars作为字符序列使用,而所有.NET字符串本质上都是如此。现在你正在从字符串中四次删除所有逗号。 - Joel Mueller
@JoelMueller,感谢您的反馈!由于我只需要删除句号、逗号、问号和感叹号,所以没有必要检查大写和小写字母并调用两次Replace。我只改变了代码一次调用它:to.str.Replace(chr |> string, ""),当我调用stripchars函数时,我去掉了额外的逗号:((stripchars "?.!," str).Split ' ') |> Array.toList。我想这仍然是一个相当昂贵的操作,对于大字符串来说。 - Great Cubicuboctahedron
1个回答

4
正如Guy Coder在上面的评论中指出的那样,该函数的主体格式不太规范。如果你将累加器函数提取到一个内部嵌套函数中,这样可能会更易读:
let stripchars chars str =
    let removeOneChar (str : string) chr =
        str.Replace(chr |> Char.ToUpper |> string, "").Replace(chr |> Char.ToLower |> string, "")
    Seq.fold removeOneChar str chars

这个函数的返回值是最后一个表达式:Seq.fold removeOneChar str charsremoveOneChar 函数的类型为 string -> char -> string

谢谢您的解释!您重新格式化的函数非常好用,确实更易读。 - Great Cubicuboctahedron

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接