如何在F#中连接字符串列表?

29

我目前正在尝试这个,但是我还没有完全弄清楚方法签名... 有人能帮忙吗?messages是seq [string]的字段

let messageString = List.reduce(messages, fun (m1, m2) -> m1 + m2 + Environment.NewLine)
5个回答

49
> String.concat " " ["Juliet"; "is"; "awesome!"];;
val it : string = "Juliet is awesome!"

这是正确的方法,注意这里的String指的是F# Core.String库,默认已导入:https://msdn.microsoft.com/en-us/library/ee353761.aspx - chillitom
4
"朱丽叶是太棒了!" |> String.concat " ";; - Sergey Kostrukov

48

不完全是你想要的,但是

let strings = [| "one"; "two"; "three" |]
let r = System.String.Concat(strings)
printfn "%s" r

你可以这样做

let strings = [ "one"; "two"; "three" ]
let r = strings |> List.fold (+) ""
printfn "%s" r
或者
let strings = [ "one"; "two"; "three" ]
let r = strings |> List.fold (fun r s -> r + s + "\n") ""
printfn "%s" r

我选择了折叠选项。虽然不是最简洁的方法,但我正在尝试不同的方法来掌握这门语言...谢谢 - mwjackson
1
第三种方法可以直接使用 Seq.fold (+) ""。相对于 reduce,它的好处是如果输入序列为空,也不会抛出“输入序列为空”的异常。 - Jason Kleban

5

如果你只是简单的字符串连接,我建议使用String.concat方法。如果你需要进行更复杂的格式化操作,那么我建议使用StringBuilder。

(StringBuilder(), [ "one"; "two"; "three" ])
||> Seq.fold (fun sb str -> sb.AppendFormat("{0}\n", str))

2

再多说一句,

当你处理字符串时,最好使用标准的字符串函数。

以下代码是用于EulerProject问题40的。

let problem40 =
    let str = {1..1000000} |> Seq.map string |> String.concat ""
    let l = [str.[0];str.[9];str.[99];str.[999];str.[9999];str.[99999];str.[999999];]
    l |> List.map (fun x-> (int x) - (int '0')) |> List.fold (*) 1

如果上面程序的第二行使用fold而不是concat,它将变得非常缓慢,因为每次fold迭代都会创建一个新的长字符串。

1
System.String.Join(Environment.NewLine, List.to_array messages)

或者使用你的折叠(请注意,这样做效率更低)

List.reduce (fun a b -> a ^ Environment.NewLine ^ b) messages

2
我相信 StringBuilder 比字符串连接算法更快。 - codebliss
@Dario,使用^和Env.NewLine而不是+和"\n"的目的是什么? - elmattic
^ 不是字符串连接运算符吗?我使用 Env.Newline 是因为它在问题中被使用了。 - Dario
没错。我以为它只是用于 OCaml 交叉编译的目的。 - elmattic
1
我不了解OCaml,但我认为在非算术目的中使用(+)是一种不好的做法。 - Dario
显示剩余2条评论

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