2009-11-19 37 views
14

Trong F # tôi muốn chuyển đổi một danh sách các ký tự thành một chuỗi. Xét đoạn mã sau:Làm thế nào để thay đổi danh sách ký tự thành chuỗi?

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

Nếu tôi chỉ đơn giản là làm lChars.ToString, tôi nhận được "[ 'a'; 'b'; 'c']". Tôi đang cố gắng để có được "abc". Tôi nhận ra rằng tôi có thể làm List.reduce để có được hiệu ứng tôi đang tìm kiếm nhưng có vẻ như có một số nguyên thủy được xây dựng trong thư viện để làm điều này.

Để đưa ra một ngữ cảnh nhỏ cho điều này, tôi đang thực hiện một số thao tác trên các ký tự riêng lẻ trong một chuỗi và khi tôi hoàn thành, tôi muốn hiển thị chuỗi kết quả.

Tôi đã cố gắng googling này và không có niềm vui theo cách đó. Tôi có cần phải chỉ cần cắn viên đạn và xây dựng một biểu thức List.reduce để làm điều này chuyển đổi hoặc là có một số cách thanh lịch hơn để làm điều này?

Trả lời

23

Các bạn đã thử

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

mới System.String (lchars |> Array.of_list) công trình cũng như vậy. – Juliet

+0

@ JaredPar, cảm ơn! Chỉ cần những gì bác sĩ đã ra lệnh. Tôi nghĩ rằng phải có một số cách đơn giản để có được tại chuỗi tôi muốn. @Juliet, bạn nên đăng câu trả lời đó :-) Tôi đã bỏ phiếu vì nó cũng là một gợi ý tuyệt vời. –

+3

Nếu bạn đang sử dụng .NET 4 hoặc mới hơn, 'System.String.Concat (lChars)' cũng thực hiện thủ thuật. –

2
['a';'b';'c'] |> List.fold_left (fun acc c -> acc^(string c)) "" 

được sửa đổi: đây lại là một cách hài hước để làm nhiệm vụ của bạn:

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 

Đáng buồn thay, chỉ cần mở rộng System.String với thành viên 'Zero' không cho phép sử dụng List.sum với chuỗi.

Đã chỉnh sửa (câu trả lời cho Juilet): Có, bạn nói đúng, gấp trái là chậm. Nhưng tôi biết chậm hơn đúng gấp :):

#r "FSharp.PowerPack" 

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

và dĩ nhiên là có nhanh chóng và đơn giản:

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

Một điều @ssp, tôi đã thử ghép một chuỗi với toán tử^và trình biên dịch đã cho tôi một cảnh báo về khả năng tương thích OCaml. Đó là, nó cảnh báo tôi rằng tôi nên sử dụng + để nối chuỗi. –

+3

fold_left rất thú vị, nhưng bạn cần phải nhớ rằng các chuỗi phụ thêm là O (n), và thêm chuỗi một char tại một thời điểm là O (n^2)! – Juliet

6

Có bao nhiêu cách để bạn có thể xây dựng một chuỗi trong F #? Dưới đây là một số ít:

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 có thể thú vị? Tôi quay hw1..3 vào chức năng và nuôi dưỡng họ một danh sách 500000 ký tự ngẫu nhiên:

  • hw1: 51ms
  • hw2: 16ms
  • hw3: er ... đủ lâu để phát triển một bộ râu? Tôi nghĩ nó chỉ ăn hết bộ nhớ của tôi.
1

Và tôi sử dụng 'sprintf' Dường như với tôi dễ dàng hơn:

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) 
+0

thụt lề mã của bạn bằng 4 dấu cách để định dạng tốt hơn –

+1

Dấu ngoặc nhọn cho là gì? –

0

Các giải pháp sau đây làm việc cho tôi:

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

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

let resultBuildString = buildString charList 
+0

Lưu ý - đây là danh sách các chuỗi chứ không phải ký tự. Ngoài ra, bạn vừa thực hiện lại List.fold –

Các vấn đề liên quan