字典上的F#迭代

字典上的F#迭代,f#,F#,我只是从F#开始,我想迭代字典,得到键和值 所以在C#中,我会说: IDictionary resultSet = test.GetResults; foreach (DictionaryEntry de in resultSet) { Console.WriteLine("Key = {0}, Value = {1}", de.Key, de.Value); } 我似乎找不到在F#中实现这一点的方法(反正也不是编译的) 有谁能建议用F#表示的等效代码吗 干杯 Crush你的字典是什么

我只是从F#开始,我想迭代字典,得到键和值

所以在C#中,我会说:

IDictionary resultSet = test.GetResults;
foreach (DictionaryEntry de in resultSet)
{
    Console.WriteLine("Key = {0}, Value = {1}", de.Key, de.Value);
}
我似乎找不到在F#中实现这一点的方法(反正也不是编译的)

有谁能建议用F#表示的等效代码吗

干杯


Crush

你的字典是什么类型的

如果它是非泛型的
IDictionary
,正如您的代码片段所建议的,那么请尝试以下操作(在F#中,
for
不会隐式插入转换,因此您需要添加
Seq.cast
以获得一个可以轻松使用的类型化集合):

如果您使用的是不可变的F#
映射
类型(这是在F#中编写函数代码时最好使用的类型),那么您可以使用Pavel的解决方案,也可以使用
for
循环和
键值
活动模式,如下所示:

for KeyValue(k, v) in dict do
  // 'k' is the key, 'v' is the value
在这两种情况下,您可以使用
for
或各种
iter
功能。如果您需要执行一些具有副作用的操作,那么我更喜欢
for
循环(这不是我提到的第一个答案:-),因为这是一种为此目的而设计的语言构造。对于函数处理,您可以使用各种函数,如
Seq.filter
等。

(这是一个比Tomas的答案更短的答案,直截了当)。字典是可变的,在F中,使用映射(不可变)更自然。因此,如果您正在处理
map:map
,请通过以下方式迭代:

for KeyValue(key,value) in map do
    DoStuff key value

好奇-为什么printf在字符串末尾有一个\n而不仅仅是printfn?每当我看到
printfn
,我都会问相反的问题。当然,没有理由,只是个人偏好。对于有副作用的方法(函数?)来说,循环调用是很好的。但是
iter
的全部要点也是执行副作用(从其类型可以看出),因此它也是“为此目的而设计的”。。。(当然,这并不是说的
是劣等的;事实上,我只是不知道
KeyValue
。@Pavel:是的,
iter
也是为此而设计的。然而,我的印象是,
iter
是从OCaml继承而来的,实现这一点的方法是使用
for
(不过这可能是个人的偏好)。一般来说,我认为如果你在做一些适合语言结构的事情时,语言结构比库函数更可取。
iter
的优点是,当你在做一些其他事情时(例如
filter
map
),它可以很好地与管道语法相协调-它作为管道中的最后一步清晰可见,而对于
for
,它则与众不同。另一方面,它是可兑换的。因此,我不认为这只是一个遗留问题(最终,如果它只是遗留问题,它就不会出现在
Seq
)。还有
iteri
iter2
和朋友,他们有一些在
for
中没有的额外功能(除非你先使用
zip
mapi
),一旦你开始使用它们,普通的
iter
更为一致。@Pavel:关于管道良好工作的观点是很好的。在本例中,我还使用了
iter
(以及
可观察。在处理事件时添加
)。咖喱是另一个好的方面(我偶尔也会用
iter
当我可以用咖喱的时候)。然而,我也看到过使用
iter
使代码看起来更“实用”的代码,唯一的结果是它看起来不那么可读。。。我认为在F#中的可读性方面必须更加小心(因为可能(?)更容易编写看起来吓人的代码)
for entry in dict do
  // use 'entry.Value' and 'entry.Key' here
for KeyValue(k, v) in dict do
  // 'k' is the key, 'v' is the value
for KeyValue(key,value) in map do
    DoStuff key value