わかりました、F# の学習を始めたばかりです。私は大学などで関数型言語にある程度触れていますが、F# などの言語での実際のプログラミングに関しては、まだかなり未熟です。
日常的に私は C# で作業していますが、今日は会社のコード ベースに時間を費やし、F# の観点から見る機会がありました。現実的なビジネス環境で言語の感触をつかむために、C# コードの一部を F# で書き直してみることにしました。
以下は、私が翻訳に苦労したいくつかの C# コードの言い換えです。
// MyData is a class with properties Id, Analysis, and some other relevant properties
// Each pair of (Id, Analysis) is (should be) distinct
IEnumerable<MyData> data = // fetch from DB...
// dataDict[id[analysis]] = MyData object (or "row") from DB
var dataDict = new Dictionary<String, Dictionary<String, MyData>> ();
foreach(var d in data)
{
if(!dataDict.ContainsKey(d.Id))
dataDict.Add(d.Id, new Dictionary<string, MyData>());
if (dataDict[d.Id].ContainsKey(d.Analysis))
{
logger.Warn(String.Format("Id '{0}' has more than one analysis of type '{1}',
rows will be ignored", d.Id, d.Analysis));
}
else
{
dataDict[d.Id].Add(d.Analysis, d);
}
}
ループを「機能的な」方法で書き直そうとした結果、次のコードが得られましたが、それほど良いとは思いません。
let dataDict =
dict [
for d in data
|> Seq.distinctBy(fun d -> d.Id) -> d.Id,
dict [
for x in data |> Seq.filter(fun a -> a.Id = d.Id) -> x.Analysis, x
]
]
このコードにはいくつかの問題があります:
- (ID、分析) ペアが重複している場合、警告は記録されず、さらに悪いことに
- for と Seq.filter を使用して、データを (少なくとも) 2 回実行します。
どうすればこれを改善できますか? 私はそれをすべて間違っていますか?