F#,char seq - >字符串

24 string f# char seq

一个快速的问题,可能更多的是一个咆哮(但我希望改为开悟).

在F#中,字符串与Seq兼容,因此"abcd"|> Seq.map f将对字符串起作用.

这是处理字符串的绝佳工具,例如从字符串中获取前5个字符:

"abcdef01234567" |> Seq.take 5
Run Code Online (Sandbox Code Playgroud)

或删除重复的字符:

"abcdeeeeeee" |> Seq.distinct
Run Code Online (Sandbox Code Playgroud)

问题是,一旦你有了char seq结果,将它再次转换回字符串变得非常尴尬,String.concat""要求成员是字符串,所以我最终做了很多:

"abcdef01234567" 
|> Seq.take 5
|> Seq.map string
|> String.concat ""
Run Code Online (Sandbox Code Playgroud)

这么多,我有90%的项目使用的功能:

let toString : char seq -> string = Seq.map string >> String.concat ""
Run Code Online (Sandbox Code Playgroud)

我觉得这已经超过了顶层,但是在我想找到另一种选择的地方,我遇到了令人发指的事情,比如StringBuilder或内联lambda并使用new:

"abcdef01234567" 
|> Seq.take 5
|> Seq.toArray 
|> fun cs -> new string (cs) (* note you cannot just |> string *)
Run Code Online (Sandbox Code Playgroud)

我希望在语言中看到的(也许是疯狂的)期望当在字符串上使用Seq时,结果表达式中的类型签名应该是字符串 - >字符串.意思是,出现的是什么."abcd"|> Seq.take 3 ="abc".

有没有理由在这种情况下我对高级字符串操作的期望是错误的?

有没有人建议以一种不错的方式接近这个,我觉得我必须遗漏一些东西.

Joh*_*man 23

我自己就是在研究这个问题.我发现System.String.Concat工作得很好,例如

"abcdef01234567" |> Seq.take 5 |> String.Concat;;
Run Code Online (Sandbox Code Playgroud)

假设你已经打开了System.

  • 只是为了弄清楚。System.String 中有两种静态连接方法。Concat & concat - 区分大小写。 (2认同)

Jac*_* P. 12

Seq模块中的函数只处理序列 - 也就是说,当你用a调用它们时string,它们只"看到"a Seq<char>并相应地操作它.即使他们进行了特殊检查以查看参数是否为a string并采取了一些特殊操作(例如,仅针对字符串的函数的优化版本),他们仍然必须将其作为Seq<char>安抚F#类型系统来返回- - 在这种情况下,你需要在任何地方检查返回值,看看它是否真的是一个string.

好消息是F#内置了一些您正在撰写的代码的快捷方式.例如:

"abcdef01234567" |> Seq.take 5
Run Code Online (Sandbox Code Playgroud)

可以缩短为:

"abcdef01234567".[..4]  // Returns the first _5_ characters (indices 0-4).
Run Code Online (Sandbox Code Playgroud)

您仍然必须使用其他一些Seq,或编写您自己的优化实现来操作字符串.

这是一个在字符串中获取不同字符的函数:

open System.Collections.Generic

let distinctChars str =
    let chars = HashSet ()
    let len = String.length str
    for i = 0 to len - 1 do
        chars.Add str.[i] |> ignore
    chars
Run Code Online (Sandbox Code Playgroud)


Lee*_*Lee 7

F#有一个String模块,其中包含一些Seq专门用于字符串的模块功能.


Cam*_*art 5

自从 5 年前提出这个问题以来,F# 已经获得了将构造函数用作函数的能力。我会使用String(Char[])将字符转换为字符串。您可以在 F# 序列或 F# 列表之间进行转换,但我也可能只使用使用String.ToCharArray方法的 F# 数组模块。

printfn "%s" ("abcdef01234567".ToCharArray() |> Array.take 5 |> String)
Run Code Online (Sandbox Code Playgroud)

如果你真的想使用 achar seq那么你可以像这样将它管道到一个 String :

printfn "%s" ("abcdef01234567" |> Seq.take 5 |> Array.ofSeq |> String)
Run Code Online (Sandbox Code Playgroud)