如何在F#中使用ToDictionary功能?

8
我有一个C#示例,它将从整数数组中创建一个奇数和偶数数字的字典:
int[] values = new int[]
{
    1,
    2,
    3,
    5,
    7
};

Dictionary<int, string> dictionary = 
           values.ToDictionary(key => key, val => (val % 2 == 1) ? "Odd" : "Even");

// Display all keys and values.
foreach (KeyValuePair<int, string> pair in dictionary)
{
    Console.WriteLine(pair);
}

输出结果为:

[1, Odd]
[2, Even]
[3, Odd]
[5, Odd]
[7, Odd]

我希望使用ToDictionary在F#中实现类似的功能,目前已经有了以下代码:

let values = [| 1; 2; 3; 5; 7 |]

let dictionary = values.ToDictionary( ??? )

// Display all keys and values.
for d in dictionary do
    printfn "%d %s" d.Key d.Value

但是我应该如何在ToDictionary内部编写逻辑呢?


@Jim Garrison:我尝试了Daniel的答案,它有效。 - brinch
2个回答

14

你当然可以在F#中使用ToDictionary(以及所有其他LINQ方法),但有时使用来自F#库的函数更符合惯用法。

如果我想创建这个字典,我会使用类似于以下的代码:

let values = [| 1; 2; 3; 5; 7 |]
let dictionary = dict [ for v in values -> v, if v % 2 = 1 then "Odd" else "Even" ]

这里dict是一个 F# 库函数,它从包含键和值的元组中创建字典(元组使用,创建,因此我们将v用作键,字符串用作值)。


3
要使用 dict,您需要添加 open ExtraTopLevelOperators。此外,在这种情况下,字典将是不可变的 IDictionary<int, string>Add()Remove() 等操作将抛出异常。 - Petr
要使用 Dictionary 构造函数来获取 Dictionary 而不是 IDictionary,例如:new Dictionary<string,obj>( dictionary ) - Maxim Kitsenko

4

像这样:

ToDictionary(id, fun v -> if v % 2 = 1 then "Odd" else "Even")

谢谢!那么第一个参数必须叫做“id”吗? - brinch
2
No. id 是一个内置函数,等同于 fun x -> x。请参阅 MSDN 上的文档(https://msdn.microsoft.com/en-us/library/ee353607.aspx)。 - Daniel
2
如果我使用“id”作为第一个参数,它可以工作。但是,如果我用“fun key -> key”替换你的“id”,输出将不再正确。 - brinch
4
在这种情况下,你需要将 fun key -> key 放在括号中:ToDictionary((fun key -> key), fun v -> if v % 2 = 1 then "Odd" else "Even") - Petr
1
这是因为如果不这样做,编译器会认为你的函数返回一个元组,而不是你将多个参数传递给 ToDictionary - N_A

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接