String 如何将字符列表更改为字符串?

String 如何将字符列表更改为字符串?,string,f#,String,F#,在F#中,我想将字符列表转换为字符串。考虑下面的代码: let lChars = ['a';'b';'c'] 如果我只做lChars.ToString,我得到“['a';'b';'c']”。我在试着读“abc”。我意识到我可能可以做一个List.reduce来获得我想要的效果,但似乎应该在库中内置一些原语来实现这一点 为了给它一点上下文,我正在对字符串中的单个字符进行一些操作,当我完成时,我想显示结果字符串 我试过用谷歌搜索这个,但没有乐趣。我是否需要咬紧牙关,构建一个List.reduce表

在F#中,我想将字符列表转换为字符串。考虑下面的代码:

let lChars = ['a';'b';'c']
如果我只做lChars.ToString,我得到“['a';'b';'c']”。我在试着读“abc”。我意识到我可能可以做一个List.reduce来获得我想要的效果,但似乎应该在库中内置一些原语来实现这一点

为了给它一点上下文,我正在对字符串中的单个字符进行一些操作,当我完成时,我想显示结果字符串

我试过用谷歌搜索这个,但没有乐趣。我是否需要咬紧牙关,构建一个List.reduce表达式来进行此转换,还是有更优雅的方法来实现此转换?

您尝试过吗

System.String.Concat(Array.ofList(lChars))
编辑: 以下是完成任务的另一种有趣方式:

type t =
  | N
  | S of string
  static member Zero
    with get() = N
  static member (+) (a: t, b: t) = 
    match a,b with
      | S a, S b -> S (a+b)
      | N, _ -> b
      | _, N -> a

let string_of_t = function
  |N -> ""
  |S s -> s

let t_of_char c = S (string c)

['a'; 'b'; 'c'] |> List.map t_of_char |> List.sum |> string_of_t
遗憾的是,仅扩展具有“Zero”成员的System.String不允许将List.sum与字符串一起使用

编辑(对Juilet的回答): 是的,你是对的,左折很慢。但我知道更慢的右折叠:):

当然,还有快速简单的方法:

new System.String(List.to_array ['1';'2';'3'])

有多少种方法可以用F#构建字符串? 还有一把:

let chars = ['H';'e';'l';'l';'o';',';' ';'w';'o';'r';'l';'d';'!']

//Using an array builder
let hw1 = new string [|for c in chars -> c|]

//StringBuilder-Lisp-like approach
open System.Text
let hw2 = 
    string (List.fold (fun (sb:StringBuilder) (c:char) -> sb.Append(c)) 
                      (new StringBuilder())
                       chars)

//Continuation passing style
let hw3 =
    let rec aux L k =
        match L with
        | [] -> k ""
        | h::t -> aux t (fun rest -> k (string h + rest) )
    aux chars id
编辑:计时可能很有趣?我将hw1..3转换为函数,并为它们提供了500000个随机字符的列表:

  • hw1:51毫秒
  • hw2:16ms
  • hw3:呃。。。留胡子的时间够长吗?我想它吞噬了我所有的记忆

    • 我使用“sprintf”在我看来更容易:

      let t = "Not what you might expect"
      let r = [ for i in "aeiou" -> i]
      let q = [for a in t do if not (List.exists (fun x -> x=a) r) then yield a]
      let rec m  = function  [] -> "" | h::t ->  (sprintf "%c" h) + (m t)
      printfn "%A"  (m q)
      

      以下解决方案适合我:

      let charList = ["H";"E";"L";"L";"O"]
      
      let rec buildString list = 
          match list with
          | [] -> "" 
          | head::tail -> head + (buildString tail)
      
      let resultBuildString = buildString charList
      

      没有在这里看到这个,所以:

      let stringFromCharList (cl : char list) =
          String.concat "" <| List.map string cl
      
      编辑:

      我不喜欢这种语法回到这里,所以这里有一个更规范的功能:

      ['a'..'z'] |> List.map string |> List.reduce (+)
      
      
      |>Array.map字符串
      |>Array.reduce(+)
      
      或者像其他人发布的那样:

      System.String.Concat([|“w”;“i”;“l”;“l”|])
      
      new System.String(lchars |>Array.of_list)也同样有效。@JaredPar,谢谢!正是医生要的。我想一定有一些简单的方法可以得到我想要的字符串@朱丽叶,你应该把它作为一个答案:-)我会投票支持它,因为这也是一个很好的建议。如果你使用的是.NET 4或更高版本,
      System.String.Concat(lChars)
      也起作用。
      let result=lChars |>Array.ofList |>String
      在F#4.0有一件事@ssp中也起作用,我确实尝试将字符串与^operator连接起来,编译器给了我一个关于OCaml兼容性的警告。也就是说,它警告我应该使用+来连接字符串。fold_left很有趣,但您需要记住,追加字符串是O(n),每次追加一个字符的字符串是O(n^2)!大括号是什么意思?
      让r=List.ofSeq“aeiou”
      对我来说似乎更简单。注意-这是字符串列表,而不是字符列表。另外,您刚刚重新实现了List.fold这不是正确的答案,但它很有用,谢谢您上一个版本很好,而且一切都很好,但它是列表大小的二次型。/shugh我想,不要在大列表上使用它。如何降低时间复杂度?
      let stringFromCharList (cl : char list) =
          String.concat "" <| List.map string cl
      
      > stringFromCharList ['a'..'d'];;
      val it : string = "abcd"
      
      ['a'..'z'] |> List.map string |> List.reduce (+)