【问题标题】:How To Change List of Chars To String?如何将字符列表更改为字符串?
【发布时间】:2010-12-18 11:18:30
【问题描述】:

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

let lChars = ['a';'b';'c']

如果我只是简单地执行 lChars.ToString,我会得到 "['a';'b';'c']"。我正在尝试获取“abc”。我意识到我可能会做一个 List.reduce 来获得我正在寻找的效果,但似乎应该在库中内置一些原语来做到这一点。

为了提供一点上下文,我正在对字符串中的单个字符进行一些操作,完成后,我想显示结果字符串。

我试过用谷歌搜索这个,但那样没有乐趣。我是否需要硬着头皮构建一个 List.reduce 表达式来执行此转换,还是有更优雅的方法来执行此操作?

【问题讨论】:

    标签: string f#


    【解决方案1】:
        [|'w'; 'i'; 'l'; 'l'|]
        |> Array.map string
        |> Array.reduce (+)
    

    或作为其他人发布的:

        System.String.Concat([|'w'; 'i'; 'l'; 'l'|])
    

    【讨论】:

      【解决方案2】:

      这里没看到这个,所以:

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

      "" 只是一个空字符串。

      FSI 输出:

      > stringFromCharList ['a'..'d'];;
      val it : string = "abcd"
      

      编辑:

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

      ['a'..'z'] |> List.map string |> List.reduce (+)
      

      【讨论】:

      • 最后一个版本很好,一切都很好,但它的列表大小是二次的。
      • /shrug 不要在大名单上使用它,我猜。您将如何降低时间复杂度?
      【解决方案3】:

      以下解决方案适用于我:

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

      【讨论】:

      • 注意 - 这是一个字符串列表,而不是字符。此外,您刚刚重新实现了 List.fold
      • 这不是正确的答案,但它很有用,谢谢
      【解决方案4】:

      而且我使用 '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 r = List.ofSeq "aeiou" 对我来说似乎更简单。
      【解决方案5】:
      ['a';'b';'c'] |> List.fold_left (fun acc c -> acc ^ (string c)) ""
      

      编辑: 这是完成任务的另一种有趣方式:

      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
      

      遗憾的是,仅使用“零”成员扩展 System.String 不允许将 List.sum 与字符串一起使用。

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

      #r "FSharp.PowerPack"
      
      List.fold_right (String.make 1 >> (^)) ['a';'b';'c'] ""
      

      当然还有快速简单的:

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

      【讨论】:

      • 一件事@ssp,我确实尝试使用 ^ 运算符连接一个字符串,编译器给了我一个关于 OCaml 兼容性的警告。也就是说,它警告我应该使用 + 来连接字符串。
      • fold_left 很有趣,但是你需要记住,附加字符串是 O(n),每次附加一个字符是 O(n^2)!
      【解决方案6】:

      在 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:16 毫秒
      • hw3:呃……长到可以留胡子?我认为它只是吞噬了我所有的记忆。

      【讨论】:

        【解决方案7】:

        你试过了吗

        System.String.Concat(Array.ofList(lChars))
        

        【讨论】:

        • new System.String(lchars |> Array.of_list) 也同样有效。
        • @JaredPar,谢谢!正是医生吩咐的。我想一定有一些简单的方法可以得到我想要的字符串。 @Juliet,您应该将其发布为答案 :-) 我会投票赞成,因为这也是一个很好的建议。
        • 如果您使用 .NET 4 或更高版本,System.String.Concat(lChars) 也可以解决问题。
        • let result = lChars |&gt; Array.ofList |&gt; String 也适用于 F# 4.0
        猜你喜欢
        • 2015-10-24
        • 2015-10-28
        • 2012-05-24
        • 1970-01-01
        • 2012-05-09
        • 2013-12-07
        • 2021-07-21
        • 2015-10-24
        • 1970-01-01
        相关资源
        最近更新 更多