如何迭代F#中的哈希表?

时间:2015-04-01 13:40:08

标签: f# hashtable

let dic = Environment.GetEnvironmentVariables()
dic
|> Seq.filter( fun k -> k.Contains("COMNTOOLS"))

无法编译。 我尝试过Array.filter, Seq.filter, List.filter 我试过让dic.Keys进行迭代,但F#似乎不希望我强迫KeyCollection加入IEnumerable

我已尝试将哈希表向上转换为IEnumerable<KeyValuePair<string,string>>

如何查看从Environment.GetEnvironmentVariables()返回的哈希表?

2 个答案:

答案 0 :(得分:2)

由于Environment.GetEnvironmentVariables()返回非通用IDictionary,并且它将键/值对存储在DictionaryEntry中,您必须先使用Seq.cast

let dic = Environment.GetEnvironmentVariables()

dic
|> Seq.cast<DictionaryEntry>
|> Seq.filter(fun entry -> entry.Key.ToString().Contains("COMNTOOLS"))

请参阅https://msdn.microsoft.com/en-us/library/system.collections.idictionary(v=vs.110).aspx的相关文档。请注意,entry.Key的类型为obj,因此必须在检查字符串包含之前将其转换为字符串。

不使用高阶函数,序列表达式可能很方便:

let dic = Environment.GetEnvironmentVariables()
seq {
    for entry in Seq.cast<DictionaryEntry> dic ->
        (string entry.Key), (string entry.Value)
}
|> Seq.filter(fun (k, _) -> k.Contains("COMNTOOLS"))

答案 1 :(得分:0)

F#Seq只能与System.Collections.Generic.IEnumerable<_>一起使用。 System.IDictionary返回的Environment.GetEnvironmentVariables不是通用的,但它实现了非通用System.Collections.IEnumerable而非System.Collections.Generic.IEnumerable<_>System.Collections.IEnumerable不包含类型信息,并允许枚举盒装类型的集合,即System.Object的实例。 无论如何System.IDictionary可以枚举为System.Collections.DictionaryEntry个对象的集合,因此您只需在其上调用Seq.cast即可。它可以让您访问KeyValue属性,但仍然将其作为对象装箱,因此您也应将其取消装箱。

let dic = System.Environment.GetEnvironmentVariables()
dic
|> Seq.cast<System.Collections.DictionaryEntry>
|> Seq.filter( fun k -> (k.Key :?> string).Contains("COMNTOOLS"))

或者您可以使用以下功能

let asStringPairSeq (d : System.Collections.IDictionary) : seq<string * string> =
    Seq.cast<System.Collections.DictionaryEntry> d
    |> Seq.map (fun kv -> kv.Key :?> string, kv.Value :?> string)

System.Environment.GetEnvironmentVariables()
|> asStringPairSeq
|> Seq.filter (fun (k,v) -> k.Contains("COMNTOOLS"))