在F#中有没有一种方法可以将[2;2;2;2;5;5;5;7;7]
映射到[4,3,2]
而不进行递归而且没有可变的?我查看了Array和List成员,发现了Reduce,但这似乎没什么帮助。
答案 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
来获得其长度。 >>
是组合运算符,它应用第一个函数,然后应用第二个函数。