How To Change List of Chars To String?
Solution 1
Have you tried
System.String.Concat(Array.ofList(lChars))
Solution 2
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.
Solution 3
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 (+)
Solution 4
['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'])
Solution 5
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)
Related videos on Youtube
Onorio Catenacci
I've been writing software for 25+ years now. I pursue ornithology as an avocation. If you want to contact me, contact me via my blog. http://onor.io av00M52Kg330gF5G
Updated on July 09, 2022Comments
-
Onorio Catenacci almost 2 years
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?
-
Juliet over 14 yearsnew System.String(lchars |> Array.of_list) works just as well too.
-
Onorio Catenacci over 14 years@JaredPar, thanks! Just what the doctor ordered. I figured there must be some simple way to get at the string I wanted. @Juliet, you should have posted that as an answer :-) I would have voted it up because it's also an excellent suggestion.
-
Onorio Catenacci over 14 yearsOne thing @ssp, I did try concatenating a string with the ^ operator and the compiler gave me a warning about OCaml compatibility. That is, it warned me that I should use + to concatenate strings.
-
Juliet over 14 yearsfold_left is fun, but you need to remember that appending strings is O(n), and appending strings one char at a time is O(n^2)!
-
Onorio Catenacci almost 11 yearsWhat are the curly braces for?
-
Sean U about 10 yearsIf you're using .NET 4 or later,
System.String.Concat(lChars)
also does the trick. -
ghord over 8 years
let result = lChars |> Array.ofList |> String
works too in F# 4.0 -
arash maleki about 8 yearsNote - this is a list of strings, not chars. Also, you have just reimplemented List.fold
-
phoog over 5 years
let r = List.ofSeq "aeiou"
seems simpler to me. -
enedil over 4 yearsThe last version is nice and everything, but it is quadratic in the size of list.
-
tykom over 4 years/shrug don't use it on big lists, I guess. How would you reduce the time complexity?
-
Petetheodddog almost 4 yearsThis wasn't the right answer but it came in useful, thank you