如何在F#中将字符串拆分为字符列表

27

我该如何在F#中将字符串拆分为字符列表?例如,如果我想将单词“Hello”拆分为字符列表,即:

"Hello" ->['H';'e';'l';'l';'o']

我尝试过 Split([| |]),但它只会根据传递的参数拆分字符串。

我也尝试过这个方法,但仍然不起作用。

let splitChar (text:string) = 
    [for c in text ->c] 

let splitChar (text:string) = 
    [for c in text do yield c] 

2
你不需要拆分任何东西。字符已经通过String.Chars属性可用。 - Panagiotis Kanavos
4个回答

31

您可以使用Seq.toList将字符串转换为字符列表:

Seq.toList "Hello"

3
这很有效,因为字符串已经是一系列字符。不需要使用Seq.toList来处理单个字符。 - Panagiotis Kanavos
1
确实,如果能澄清一下为什么OP需要特别指定输出为列表,那将会很有帮助。Seq.toList "Hello"的结果将会输出一个char list - Chad Gilbert
当我使用seq.toList时,编译器会报错:"toList字段构造函数未定义"。 - Ivan
1
Seq 中应该使用大写字母 S。此外,在你的示例中,第一个实例中的 toLIst 应该被改为 toList 并大写字母 I - Chad Gilbert

13

字符串本质上是一系列字符的序列,就像它在实现IEnumerable<char>一样。在内部,一个字符串是由char值数组组成的。这个数组通过Chars索引器公开。

您可以在字符串上使用任何Seq方法,例如:

"abc" |> Seq.iter (fun x->printfn "%c" x)

还可以获取单个字符。

您还可以使用String 模块的优化函数:

"abc" |> String.iter (fun x->printfn "%c" x)

String 模块利用 String 类的方法来提高性能。例如,String.length 函数是 String.Length 属性的别名,因此它不必像 Seq 一样迭代所有字符:

    let length (str:string) =
        let str = emptyIfNull str
        str.Length

其他函数,例如String.iter 直接使用 Chars 索引器:

    let iter (f : (char -> unit)) (str:string) =
        let str = emptyIfNull str
        for i = 0 to str.Length - 1 do
            f str.[i] 

6
在.NET中,您可以使用String.ToCharArray方法。要转换回字符串,您现在可以使用String(Char[]),因为F#将构造函数用作函数。
"Hello".ToCharArray() |> List.ofArray

使用F# Array模块可能会获得更好的性能。我猜测List.ofArrayList.ofSeq更有效率。如果这不是很重要,与Chad的答案类似,F#惯用方式是:

"Hello" |> List.ofSeq

5

我注意到有时我会最初想把某些东西分割成字符数组或者列表,但我应该更简明扼要。

let msg = "hello-world"

let resultA = 
    msg.[0..0].ToUpper() + msg.[1..].Replace('-', ' ')

let resultB = 
    Seq.toList (msg)
    |> (fun list -> (string list.Head).ToUpper() + (String.Concat(list.Tail)).Replace('-', ' '))

// val resultA : string = "Hello world"
// val resultB : string = "Hello world"

"resultA" 的方式我认为更好。

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