2013-06-30 3 views
10

저는 F #으로 작업하기 시작했으며 전형적인 idoms와 효과적인 사고 방식 및 작업 방식을 이해하려고합니다.F #의 파일 변환

작업은 탭으로 구분 된 파일을 쉼표로 구분 된 파일로 간단히 변환하는 작업입니다. 나는 다음과 같은 코드를 루프로 시작

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

: 같은 일반적인 입력 라인 모양 그때 하나의 Regex.Replace의 조작 스플릿/CONCAT 쌍을 교체

// 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) 

() :

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

그리고 지금, 마지막으로, 파이프 라인과 루프 교체 한 :

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 

모든 버전이 작동하지만 최종 버전은 나에게 가장 직관적 인 것처럼 보입니다. 더 숙련 된 F # 프로그래머가이 작업을 수행하는 방법은 무엇입니까?

+0

나는 당신이 그것을했던 것과 같은 방식으로 할 것입니다. –

+1

제 3의 버전의 마지막 줄에 익명의 함수를 남겨두고 이것을 할 것입니다 :'|> Seq.iter outFile.WriteLine' –

+1

그건 아주 좋은 것입니다. ** 회상 **, 명백한] 단순화. 감사! – akucheck

답변

11

3 가지 버전 모두 F # 전문가가 작성하는 코드는 완벽하게 멋지다고 생각합니다.

나는 일반적으로 언어 기능 (예 : for 루프 및 if 조건)을 사용하여 코드를 작성하는 편이 좋다고 생각합니다. 이것들은 필수적이지만, API가 명령형 코드 (예 : outFile.WriteLine)를 요구할 때 사용하는 것이 좋습니다. 언급했듯이이 버전으로 시작했습니다. 고차 함수를 사용

너무 좋다 - 나는 아마 내가 데이터를 변환을 쓰고 싶었다 경우에만 그렇게하고 새로운 시퀀스 또는 라인의 목록을 얻을 것이다 있지만 -이 편리 할 것입니다 당신이 대신 File.WriteAllLines를 사용한 경우 라인을 하나씩 작성합니다. 단순히 시퀀스 표현과 두 번째 버전을 포장하여 수행 할 수있는, 비록 :

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

나는 버전 중 하나를 선호하는 객관적인 이유가 있다고 생각하지 않습니다. 제 개인적인 스타일 선호는 for과 리팩토링 (refactor)을 사용하여 표현식을 시퀀싱하는 것입니다 (필요하다면). 그러나 다른 것들은 그렇지 않을 수 있습니다.

+0

고마워요, 토마스 - 많이 감사합니다. – akucheck