2015-04-01 101 views
-1
let dic = Environment.GetEnvironmentVariables() 
dic 
|> Seq.filter(fun k -> k.Contains("COMNTOOLS")) 

无法编译。 我试过使用Array.filter, Seq.filter, List.filter 我试过只得到dic.Keys来迭代,但F#似乎并不希望我强制将KeyCollection转换为IEnumerable如何迭代F#中的散列表?

我试图向上转型哈希表到IEnumerable<KeyValuePair<string,string>>

如何走是从Environment.GetEnvironmentVariables()返回的哈希表?

+2

您应指定实际的错误,但我怀疑它与'k.Contains'做。 'k'是一个KeyValuePari <,>所以'Contains'不存在 – 2015-04-01 13:43:07

+0

当我在添加更多细节并删除实际错误而不注意的情况下输入它时,它是:*无法执行文本选择:IDictionary类型不兼容类型'seq <'a>'* – Maslow 2015-04-01 13:48:16

回答

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")) 
0

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就可以了。它会让您访问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")) 
+1

第一个代码块不能编译:* DictionaryEntry类型没有任何适当的子类型,不能用作类型测试或运行时强制的源代码*第二个块没有因为似乎没有'System.Collections.Dictionary',并且给出了额外的错误:*类型'Microsoft.FSharp.Collections.seq <_>'需要1个类型参数(s),但给出2 *可能应该是'string * string'。 – Maslow 2015-04-01 14:28:35