简体   繁体   English

按 int (Haskell) 对 ('String', int) 的列表进行排序

[英]Sorting a list of ('String', int) by its int (Haskell)

I am brand new to Haskell, so I'm still learning a lot of things.我是 Haskell 的新手,所以我还在学习很多东西。 I was given a list of name and age, and I need to sort them in both alphabetical order and in increasing order using their age.我得到了一份姓名和年龄列表,我需要按字母顺序和年龄递增顺序对它们进行排序。 I managed to sort the list alphabetically, but I'm unsure how to do it using its age values.我设法按字母顺序对列表进行排序,但不确定如何使用其年龄值进行排序。 What can I change in the code below?我可以在下面的代码中更改什么? Thank you for your help.谢谢您的帮助。

qsort :: (Ord a) => [a] -> [a]
-- check to see if the list is empty
qsort [] = []
qsort [x] = [x] -- Single element list is always sorted
qsort [x, y] = [(min x y), (max x y)]
-- x is the pivot, left quicksort returns smaller sorted and right quicksort bigger sorted
qsort (x:xs) =
  qsort [a | a <- xs, a <= x] ++ [x] ++ qsort [a | a <- xs, a > x]


people=[("Steve",20),("Smith",31),("Kris",19),("Beth",21)]

main = do
  print(qsort people) -- sort alphabetically

First, let's simplify your function a bit.首先,让我们稍微简化一下您的 function。 Both the [x] and [x, y] cases are redundant: they are completely captured by the (x:xs) case. [x][x, y]情况都是多余的:它们完全被(x:xs)情况捕获。 So let's remove those.所以让我们删除那些。

qsort :: (Ord a) => [a] -> [a]
qsort [] = []
qsort (x:xs) =
  qsort [a | a <- xs, a <= x] ++ [x] ++ qsort [a | a <- xs, a > x]

Now, currently we assume that the type of our list and the type we're sorting by are the same.现在,目前我们假设我们的列表类型和我们排序的类型是相同的。 We call them both a .我们称它们a . Let's instead have two types: a will be the type of our list and b will be the type we want to sort by.让我们改为有两种类型: a将是我们列表的类型, b将是我们要排序的类型。 Only b has to satisfy Ord , and we'll need a function to convert an a into a b so we can sort our list.只有b必须满足Ord ,我们需要一个 function 将a转换为b ,以便我们对列表进行排序。 This is our desired type这是我们想要的类型

qsort :: (Ord b) => (a -> b) -> [a] -> [a]

Our base case is basically the same, except that we ignore the function argument.我们的基本情况基本相同,只是我们忽略了 function 参数。

qsort _ [] = []

In our recursive case, we compare by applying the function f:: a -> b and then using <= or > .在我们的递归案例中,我们通过应用 function f:: a -> b然后使用<=>进行比较。

qsort f (x:xs) =
    qsort f [a | a <- xs, f a <= f x] ++ [x] ++ qsort f [a | a <- xs, f a > f x]

Now we can sort by whatever Ord type we want.现在我们可以按我们想要的任何Ord类型进行排序。 We can sort by the first element of a tuple我们可以按元组的第一个元素排序

-- Note: (fst :: (a, b) -> a) is in Prelude
print (qsort fst people)

or the second或第二个

-- Note: (snd :: (a, b) -> b) is in Prelude
print (qsort snd people)

both by their natural sorting order.两者都按其自然排序顺序。

If we want to sort in the opposite order (descending rather than ascending), we can use Down as our function. If we want to sort by some complex order, we can always use the newtype pattern .如果我们想以相反的顺序排序(降序而不是升序),我们可以使用Down作为我们的 function。如果我们想按一些复杂的顺序排序,我们总是可以使用newtype 模式

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM