F#计数在列表中重复

时间:2014-01-19 19:42:23

标签: recursion f#

在F#中有没有一种方法可以将[2;2;2;2;5;5;5;7;7]映射到[4,3,2]而不进行递归而且没有可变的?我查看了Array和List成员,发现了Reduce,但这似乎没什么帮助。

2 个答案:

答案 0 :(得分:11)

您可以使用Seq.countBy快速实施。使用F#interactive,它看起来像这样:

> [2;2;2;2;5;5;5;7;7] |> Seq.countBy id;;
val it : seq<int * int> = seq [(2, 4); (5, 3); (7, 2)]

如果您只想要计数(而不是重复的值),您只需将结果输入Seq.map

> [2;2;2;2;5;5;5;7;7] |> Seq.countBy id |> Seq.map snd;;
val it : seq<int> = seq [4; 3; 2]

请注意,您可以使用Seq.groupBy实现此目的,但Seq.countBy效率更高:Seq.groupBy消耗更多内存,因为它必须存储所有组,而Seq.countBy为序列中的每个键只存储一个int(计数器)。

答案 1 :(得分:4)

试试这个:

[2;2;2;2;5;5;5;7;7] |> Seq.groupBy id |> Seq.map (snd >> Seq.length)

Seq.groupBy id将列表收集到相同元素的组中 - 使用标识函数id意味着序列的元素直接用作相等性检查的“键”。这给了我们一系列与重复配对的原始元素:

 seq [(2, seq [2; 2; 2; 2]); (5, seq [5; 5; 5]); (7, seq [7; 7])]

然后对于每个内部序列,我们使用snd来获得重复序列,并使用Seq.length来获得其长度。 >>是组合运算符,它应用第一个函数,然后应用第二个函数。