【发布时间】:2021-04-21 16:08:23
【问题描述】:
我有一个代码histogram,它显示了String中所有字符的个数。
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 代码,但它仅按第一个元素(字符)排序。
import Data.List (minimum, delete)
ssort :: Ord t => [t] -> [t]
ssort [] = []
ssort xs = x : ssort (remove x xs) where
x = minimum xs
remove :: Eq a => a -> [a] -> [a]
remove _ [] = []
remove y (x:xs) | y == x = xs
| otherwise = x : remove y xs
输入: 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,我想实现自己的函数。
我怎样才能使它只比较第二个元素?
【问题讨论】:
-
也许你想做的是定义你自己的
minimum函数,然后你可以专门处理对列表。类似minimumSnd :: Ord b => [(a,b)] -> (a,b) -
@DDub 你甚至不需要额外的函数:你可以像
minimumSnd = swap . minimum . fmap swap这样实现它,这样很容易内联。 -
@bradm 的确如此,但发帖者并不是简单地询问如何获得正确答案,而是如何实现自己的功能以达到目标。我不是简单地给出答案,而是建议@Theresa 可能遵循的可能导致正确实施的路径。了解
minimum是ssort没有做发帖人想要做的事情的根本原因很重要,并且修复该实现是前进的方向。一旦理解,内联就很棒(事实上,整个事情都可以内联到sortOn snd)。
标签: list sorting haskell select histogram