List 哈斯克尔。按元组列表中的第二个元素排序
我有一个codeList 哈斯克尔。按元组列表中的第二个元素排序,list,sorting,haskell,select,histogram,List,Sorting,Haskell,Select,Histogram,我有一个code直方图,它显示了字符串中所有字符的数量 histogram :: String -> [(Char, Int)] histogram = foldr help [] where help x [] = [(x,1)] help x ((y,z):yzs) | x == y = (y,z+1) : yzs | otherwise = (y,z) : help x yzs 但结果是以混乱的顺序显示的。我想按列表的第二个元素(即按数字
直方图
,它显示了字符串中所有字符的数量
histogram :: String -> [(Char, Int)]
histogram = foldr help [] where
help x [] = [(x,1)]
help x ((y,z):yzs)
| x == y = (y,z+1) : yzs
| otherwise = (y,z) : help x yzs
但结果是以混乱的顺序显示的。我想按列表的第二个元素(即按数字)对结果进行排序。为此,我实现了ssort
code,但它只按第一个元素(char)排序
输入:ssort[('a',1),('g',6),('o',2),('f',0)]
输出:[('a',1),('f',0),('g',6),('o',2)](而不是[('f',0),('a',1),('o',2),('g',6)])
我也不想使用任何其他内置功能,比如sort、sortOn和sortBy,我想实现我自己的功能
我怎样才能做到只比较第二个元素?假设您不想同时使用
minimumBy::Foldable t=>(a->a->Ordering)->ta->a
您可以利用元组的比较方式——首先是第一个元素,然后是第二个元素。因此,您可以先交换直方图的所有元素,然后进行排序,最后再交换回:
ssortOn2 :: (Ord t1, Ord t2) => [(t1, t2)] -> [(t1, t2)]
ssortOn2 = map swap . ssort . map swap
(保持所有其他功能不变)您可以提供自己对
最小值的定义:
minimumBy2 :: Ord t2 => [(t1, t2)] -> (t1, t2)
minimumBy2 (h:t) = go h t where
go x [] = x
go x (h0:t0) = go (min x h0) t0
minimumBy2 [] = error "minimumBy2: Empty list"
然后,您可以使用它代替ssort
中的minimum
,它应该可以工作。也许您想做的是定义自己的minimum
函数,然后您可以专门处理成对列表。类似于minimumSnd::Ord b=>[(a,b)]->(a,b)
@DDub您甚至不需要额外的函数:您可以像minimumSnd=swap一样实现它。最低限度fmap交换
,很容易内联。@bradm这是真的,但海报不仅仅是问如何得到正确的答案,而是问如何实现自己的功能以达到目的。我不是简单地给出答案,而是建议@Theresa可能遵循的路径,从而实现正确的实现。理解最小值
是ssort
不能满足海报要求的根本原因,这一点很重要,解决这一问题是前进的方向。一旦理解了,内联就很好了(事实上,整个事情都可以内联到sortOn snd
)。
minimumBy2 :: Ord t2 => [(t1, t2)] -> (t1, t2)
minimumBy2 (h:t) = go h t where
go x [] = x
go x (h0:t0) = go (min x h0) t0
minimumBy2 [] = error "minimumBy2: Empty list"