1

私はF#を学び始めています。私は、オブジェクト指向プログラミングから考えを変えるのが非常に難しいと感じています。F#開発者が次のように書く方法を知りたいです。

「従来の」C#

public List<List<string>> Parse(string csvData){
    var matrix = new List<List<string>>();
    foreach(var line in csvData.Split(Environment.NewLine.ToArray(), StringSplitOptions.None)){
        var currentLine = new List<string>();
        foreach(var cell in line.Split(','){
            currentLine.Add(cell);
        }
        matrix.Add(currentLine);
    }
    return matrix;
}

「機能的な」C#

public List<List<string>> Parse(string csvData){
    return csvData.Split(Environment.NewLine.ToArray(), StringSplitOptions.None).Select(x => x.Split(',').ToList()).ToList();
}

質問は次のとおりです。以下のコードは正しいと見なされますか?

F#

let Parse(csvData:string) = 
    csvData.Split(Environment.NewLine.ToArray(), StringSplitOptions.None).ToList()
    |> Seq.map(fun x -> x.Split(',').ToList())
4

3 に答える 3

5

あなたの翻訳は私には良さそうです。C#での拡張メソッド(など)の使用は、使用しているコレクションの種類(例)に応じてfoo.Select(...)、パイプラインとF#関数(またはモジュール)の使用とほぼList同じSeqです。Arrayfoo |> Seq.map (...)

F#のLINQ拡張メソッドを使用し、それらをF#コンストラクトと混合することはまったく問題ありませんが、対応するF#関数がない場合にのみそれを行うので、サンプルで次のように記述しますToArray()ToList()

open System

let Parse(csvData:string) = 
    // You can pass the result of `Split` (an array) directly to `Seq.map`
    csvData.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.None)
    // If you do not want to get sequence of arrays (but a sequence of F# lists)
    // you can convert the result using `Seq.toList`, but I think working with
    // arrays will be actually easier when processing CSV data
    |> Seq.map(fun x -> x.Split(',') |> Seq.toList)
于 2013-01-09T14:10:07.473 に答える
3

ソリューションには、F#っぽくないものがいくつかあります。

  • ミュータブルListはF#ではResizeArrayという名前であり、Array、List、Seqなどの組み込みコレクションとしては十分にサポートされていません。
  • 多くの場合、F#でLINQを使用する必要はありません。配列、リスト、およびSeqモジュールで十分です。
  • ドット(。)構文は、パイプ演算子ではうまく機能しません。

戻り値のタイプをに変更するstring [] []と、ヘルパー関数を使用してより簡潔なコードを作成できます。

let split (delim: string) (str: string) =
    str.Split([|delim|], StringSplitOptions.RemoveEmptyEntries)

let parse (csvData: string) = 
    csvData
    |> split Environment.NewLine
    |> Array.map (split ",")
于 2013-01-09T14:11:40.363 に答える
1

このページのさまざまなソリューションには微妙な違いがあります。たとえば、C#ソリューションとパッドのソリューションは熱心ですが、F#バージョンとTomasは怠惰です。あなたとパッドはで分割されEnvironment.NewLineますが、トーマスはの任意の文字で分割されますNewLine(受け入れるオーバーロードを呼び出したので、後者が必要だと思いますStringSplitOptions)。多分これらの問題; そうでないかもしれない。

とにかく、ここにパッドの解決策の別の見方があります。

let split (delims: char[]) (str: string) =
  str.Split(delims, StringSplitOptions.RemoveEmptyEntries)

let parse csvData =
  let nl = Environment.NewLine.ToCharArray()
  [ for x in split nl csvData -> split [|','|] x ]
于 2013-01-09T15:37:19.683 に答える