如何在 F# 中迭代哈希表?
How do I iterate over a hashtable in F#?
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()
返回的哈希表?
因为 Environment.GetEnvironmentVariables()
returns 一个非泛型 IDictionary
并且它在 DictionaryEntry
中存储 key/value 对,你必须使用 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"))
F# Seq 只能与System.Collections.Generic.IEnumerable<_>
一起操作。 Environment.GetEnvironmentVariables
返回的 System.IDictionary
不是通用的,但它实现了非通用的 System.Collections.IEnumerable
而不是 System.Collections.Generic.IEnumerable<_>
。 System.Collections.IEnumerable
不包含类型信息并允许枚举装箱类型的集合,即 System.Object
的实例。
无论如何,System.IDictionary
可以枚举为 System.Collections.DictionaryEntry
个对象的集合,因此您可以简单地对其调用 Seq.cast
。它会让您访问 Key
和 Value
属性,但仍作为对象装箱,因此您也应该将它们拆箱。
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"))
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()
返回的哈希表?
因为 Environment.GetEnvironmentVariables()
returns 一个非泛型 IDictionary
并且它在 DictionaryEntry
中存储 key/value 对,你必须使用 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"))
F# Seq 只能与System.Collections.Generic.IEnumerable<_>
一起操作。 Environment.GetEnvironmentVariables
返回的 System.IDictionary
不是通用的,但它实现了非通用的 System.Collections.IEnumerable
而不是 System.Collections.Generic.IEnumerable<_>
。 System.Collections.IEnumerable
不包含类型信息并允许枚举装箱类型的集合,即 System.Object
的实例。
无论如何,System.IDictionary
可以枚举为 System.Collections.DictionaryEntry
个对象的集合,因此您可以简单地对其调用 Seq.cast
。它会让您访问 Key
和 Value
属性,但仍作为对象装箱,因此您也应该将它们拆箱。
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"))