我如何按元组的第二个元素对该列表进行分组:
[(3,2),(17,2),(50,3),(64,3)]
得到如下结果:
[[(3,2),(17,2)],[(50,3),(64,3)]]
我其实是一个新来的 haskell ......似乎爱上了它。希望你能帮助我找到一个有效的方法。
ruarlubt1#
听起来好像您已经确定需要Data.List.groupBy。
Data.List.groupBy
groupBy :: (a -> a -> Bool) -> [a] -> [[a]]
所以它需要一个二元 predicate ,也就是一个等价关系来决定如何对元素进行分组。
groupBy (\x y -> snd x == snd y) myList
其中snd是一个内置函数,用于获取元素对中的第二个元素。顺便说一句,这种“将一个函数应用于两个参数,然后将一个二进制函数应用于结果”的模式 * 非常 * 常见,尤其是在调用Data.List函数时,因此Data.Function提供on。
snd
Data.List
Data.Function
on
on :: (b -> b -> c) -> (a -> b) -> a -> a -> c
奇怪的签名,但用例正是我们想要的。
((+) `on` f) x y = f x + f y
因此,您所需的groupBy可以写为
groupBy
groupBy ((==) `on` snd)
请注意,groupBy只查找 consecutive equal元素,您没有指明您是想要连续的equal元素还是 all equal元素,但如果您想要后者,那么我不相信Haskell base提供了该函数,尽管您可以自己递归地编写它。
base
1条答案
按热度按时间ruarlubt1#
听起来好像您已经确定需要
Data.List.groupBy
。所以它需要一个二元 predicate ,也就是一个等价关系来决定如何对元素进行分组。
其中
snd
是一个内置函数,用于获取元素对中的第二个元素。顺便说一句,这种“将一个函数应用于两个参数,然后将一个二进制函数应用于结果”的模式 * 非常 * 常见,尤其是在调用
Data.List
函数时,因此Data.Function
提供on
。奇怪的签名,但用例正是我们想要的。
因此,您所需的
groupBy
可以写为请注意,
groupBy
只查找 consecutive equal元素,您没有指明您是想要连续的equal元素还是 all equal元素,但如果您想要后者,那么我不相信Haskellbase
提供了该函数,尽管您可以自己递归地编写它。