2017-10-09 30 views
1

F#中的Dictionary有一個構造函數(將Seq/List作爲輸入並輸出字典)?我寫了下面的代碼,我想要做什麼,但我只是好奇,也許它已經實現(所以我並不需要實現它自己)來自List/Seq的F#字典生成器

let DictionaryBuilder (keyFunc:'a->'b) (valueFunc:'a->'c) aList = 
    let dict = new Dictionary<'b,'c>() 
    aList 
    |> Seq.iter (fun a -> dict.Add(keyFunc a, valueFunc a)) 
    dict // return 

我知道,在C#中,可以使用.ToDictionary(使用System.Linq)

// using System.Collections.Generic; 
// using System.Linq; 
List<string> example = new List<string> {"a","b","c"}; 
Dictionary<string,string> output = example.ToDictionary(x => x+"Key", x => x+"Value"); 
// Output: {"aKey": "aValue", "bKey": "bValue", "cKey": "cValue"} 

非常感謝。

回答

1

的字典功能,它作爲簽名如下:

dict : seq<'Key * 'Value> -> IDictionary<'Key,'Value> 

所以它需要一個鍵值序列作爲輸入。這裏的關鍵是要給它一個關鍵的價值序列。在你的情況下,你可以使用地圖而不是iter。代碼行類似,但它是一種更加有效的方式。

aList 
|> Seq.map (fun a -> keyFunc a, valueFunc a) 
|> dict 

編輯

由於TheQuickBrownFox在評論中所指出的,該字典功能產生一個只讀的字典。

+0

注意'dict'生成一個只讀字典(當您嘗試添加或刪除項目時會引發異常)。你可以通過再次將該字典傳遞給Dictionary構造函數來解決這個問題:'... |> dict |> System.Collections.Generic.Dictionary' – TheQuickBrownFox

+0

好的聲明,謝謝 –

1

我會建議你只使用LINQ:

open System.Linq 
[1; 2; 3].ToDictionary(id, (*) 2) 

您可以直接使用,或將其放在你的助手的功能,如果你想用一個函數比的擴展方法。

module Seq = 
    open System.Linq 
    let toDictionary (f:'s -> 'k) (g:'s -> 'v) (xs:_ seq) = xs.ToDictionary(f, g)