2013-06-30 39 views
10

Tôi chỉ mới bắt đầu làm việc với F # và cố gắng hiểu các nguyên mẫu điển hình và cách suy nghĩ và làm việc hiệu quả.Chuyển đổi tập tin trong F #

Nhiệm vụ trong tay là một biến đổi đơn giản của tệp được phân tách bằng tab thành tệp được phân cách bằng dấu phẩy. Một dòng đầu vào điển hình sẽ trông giống như:

let line = "@ES# 01/31/2006 13:31:00 1303.00 1303.00 1302.00 1302.00 2514 0" 

Tôi bắt đầu với vòng lặp mã như thế này:

// inFile and outFile defined in preceding code not shown here 

for line in File.ReadLines(inFile) do 
    let typicalArray = line.Split '\t' 
    let transformedLine = typicalArray |> String.concat "," 
    outFile.WriteLine(transformedLine) 

sau đó tôi thay thế các cặp chia/concat hoạt động với một Regex.Replace đơn():

for line in File.ReadLines(inFile) do 
    let transformedLine = Regex.Replace(line, "\t",",") 
    outFile.WriteLine(transformedLine) 

Và bây giờ, cuối cùng, đã thay thế vòng lặp với một đường ống dẫn:

File.ReadLines(inFile) 
    |> Seq.map (fun x -> Regex.Replace(x, "\t", ",")) 
    |> Seq.iter (fun y -> outFile.WriteLine(y)) 

    // other housekeeping code below here not shown 

Trong khi tất cả các phiên bản hoạt động, phiên bản cuối cùng dường như là trực quan nhất. Đây có phải là cách một lập trình viên F # giàu kinh nghiệm thực hiện nhiệm vụ này không?

+0

Tôi sẽ làm giống như cách bạn đã làm nó –

+1

Tôi sẽ bỏ qua chức năng ẩn danh trên dòng cuối cùng của phiên bản thứ ba của bạn và chỉ cần làm điều này: '|> Seq.iter outFile.WriteLine' –

+1

Đó là một điều rất hay [và, ** nhìn lại **, rõ ràng] đơn giản hóa. cảm ơn! – akucheck

Trả lời

11

Tôi nghĩ rằng tất cả ba phiên bản là hoàn toàn tốt, mã thành ngữ mà các chuyên gia F # sẽ viết.

Tôi thường thích viết mã bằng các tính năng ngôn ngữ được tích hợp sẵn (như for vòng và điều kiện if) nếu chúng cho phép tôi giải quyết vấn đề tôi có. Đây là điều bắt buộc, nhưng tôi nghĩ việc sử dụng chúng là một ý tưởng hay khi API yêu cầu mã bắt buộc (như outFile.WriteLine). Như bạn đã đề cập - bạn bắt đầu với phiên bản này (và tôi sẽ làm như vậy).

Sử dụng chức năng bậc cao là tốt đẹp quá - mặc dù tôi có lẽ sẽ làm điều đó chỉ khi tôi muốn ghi dữ liệu chuyển đổi và nhận được một chuỗi mới hoặc danh sách các dòng - điều này sẽ có ích nếu bạn đang sử dụng File.WriteAllLines thay vì viết từng dòng một. Mặc dù, mà cũng có thể được thực hiện bằng cách đơn giản gói phiên bản thứ hai của mình với cụm chuỗi:

let transformed = 
    seq { for line in File.ReadLines(inFile) -> Regex.Replace(line, "\t",",") } 
File.WriteAllLines(outFilePath, transformed) 

Tôi không nghĩ có bất kỳ lý do khách quan để thích một trong những phiên bản. Tùy chọn phong cách cá nhân của tôi là sử dụng for và cấu trúc lại thành các biểu thức trình tự (nếu cần), nhưng những người khác có thể sẽ không đồng ý.

+0

Cảm ơn, Tomas - được nhiều người đánh giá cao. – akucheck

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