[英]Haskell. Sort by second element in the list of tuples
I have a code histogram
, which shows the number of all characters in String.我有一个代码
histogram
,它显示了字符串中所有字符的数量。
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
But the result is shown in a chaotic order.但结果以混乱的顺序显示。 I want to sort the result by the second element of the list (ie by numbers).
我想按列表的第二个元素(即按数字)对结果进行排序。 For this I implemented
ssort
code but it sorts only by the first element (char).为此,我实现
ssort
代码,但它仅按第一个元素(char)排序。
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
Input: ssort [('a',1), ('g', 6), ('o',2), ('f',0)]输入: ssort [('a',1), ('g', 6), ('o',2), ('f',0)]
Output: [('a',1),('f',0),('g',6),('o',2)] (instead of [('f',0),('a',1),('o',2),('g',6)]) Output: [('a',1),('f',0),('g',6),('o',2)] (而不是 [('f',0),('a ',1),('o',2),('g',6)])
I also don't want to use any other builtins, as sort, sortOn and sortBy, I want to implement my own function.我也不想使用任何其他内置函数,如 sort、sortOn 和 sortBy,我想实现自己的 function。
How can I make it so that only the second elements are compared?我怎样才能使它只比较第二个元素?
You may provide your own definition of minimumBy
:您可以提供自己的
minimumBy
定义:
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"
You can then use it in place of minimum
in ssort
and it should work.然后,您可以在
ssort
中使用它代替minimum
,它应该可以工作。
Assuming you don't want to use minimumBy:: Foldable t => (a -> a -> Ordering) -> ta -> a
as well.假设您也不想使用
minimumBy:: Foldable t => (a -> a -> Ordering) -> ta -> a
。
You can take advantage on how are tuples compared – first by the first element and then by the second.您可以利用元组的比较方式——首先是第一个元素,然后是第二个元素。 Therefore you can first swap all of the elements of your histogram, then sort and finally swap back:
因此,您可以首先交换直方图的所有元素,然后排序并最后交换回来:
ssortOn2 :: (Ord t1, Ord t2) => [(t1, t2)] -> [(t1, t2)]
ssortOn2 = map swap . ssort . map swap
(leaving all other functions unchanged) (保持所有其他功能不变)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.