English 中文(简体)
How To Change List of Chars To String?
原标题:
  • 时间:2009-11-19 19:44:47
  •  标签:
  • string
  • f#

In F# I want to transform a list of chars into a string. Consider the following code:

let lChars = [ a ; b ; c ]

If I simply do lChars.ToString, I get "[ a ; b ; c ]". I m trying to get "abc". I realize I could probably do a List.reduce to get the effect I m looking for but it seems like there should be some primitive built into the library to do this.

To give a little context to this, I m doing some manipulation on individual characters in a string and when I m done, I want to display the resulting string.

I ve tried googling this and no joy that way. Do I need to just bite the bullet and build a List.reduce expression to do this transformation or is there some more elegant way to do this?

最佳回答

Have you tried

System.String.Concat(Array.ofList(lChars))
问题回答

How many ways can you build a string in F#? Here s another handful:

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

Edit: timings may be interesting? I turned hw1..3 into functions and fed them a list of 500000 random characters:

  • hw1: 51ms
  • hw2: 16ms
  • hw3: er... long enough to grow a beard? I think it just ate all of my memory.

Didn t see this one here, so:

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

"" is just an empty string.

FSI output:

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

EDIT:

Didn t like this syntax coming back to this so here s a more canonically functional one:

[ a .. z ] |> List.map string |> List.reduce (+)
[ a ; b ; c ] |> List.fold_left (fun acc c -> acc ^ (string c)) ""

Edited: Here is yet another funny way to do your task:

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

Sadly, just extending System.String with Zero member does not allow to use List.sum with strings.

Edited (answer to Juilet): Yes, you are right, left fold is slow. But i know more slow right fold :) :

#r "FSharp.PowerPack"

List.fold_right (String.make 1 >> (^)) [ a ; b ; c ] ""

and of course there is fast and simple:

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

And i used sprintf seems to me easier:

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)

The following solution works for me:

let charList = ["H";"E";"L";"L";"O"]

let rec buildString list = 
    match list with
    | [] -> "" 
    | head::tail -> head + (buildString tail)

let resultBuildString = buildString charList
    [| w ;  i ;  l ;  l |]
    |> Array.map string
    |> Array.reduce (+)

or as someone else posted:

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




相关问题
Simple JAVA: Password Verifier problem

I have a simple problem that says: A password for xyz corporation is supposed to be 6 characters long and made up of a combination of letters and digits. Write a program fragment to read in a string ...

Case insensitive comparison of strings in shell script

The == operator is used to compare two strings in shell script. However, I want to compare two strings ignoring case, how can it be done? Is there any standard command for this?

Trying to split by two delimiters and it doesn t work - C

I wrote below code to readin line by line from stdin ex. city=Boston;city=New York;city=Chicago and then split each line by ; delimiter and print each record. Then in yet another loop I try to ...

String initialization with pair of iterators

I m trying to initialize string with iterators and something like this works: ifstream fin("tmp.txt"); istream_iterator<char> in_i(fin), eos; //here eos is 1 over the end string s(in_i, ...

break a string in parts

I have a string "pc1|pc2|pc3|" I want to get each word on different line like: pc1 pc2 pc3 I need to do this in C#... any suggestions??

Quick padding of a string in Delphi

I was trying to speed up a certain routine in an application, and my profiler, AQTime, identified one method in particular as a bottleneck. The method has been with us for years, and is part of a "...

热门标签