降序列表的排序

Bob*_*bys 1 sorting haskell

我试图根据平均评级对列表进行排序.我设法创建一个函数来返回平均评级和函数来过滤数据库并返回给定年份的电影.但是我如何将所有这些放在一起并获得排序的输出?你能给我一些提示吗?

我的代码是:

-- Define Film type here
type Film = (Title, Director, Year, [Rating])

-- Define database type here
type Database = [Film]

testDatabase :: [Film]
testDatabase =
  [("Casino Royale", "Martin Campbell",  2006, [("Garry",8),("Dave", 0)])
  ,("Blade Runner",  "Ridley Scott",     1982, [("Amy",  5),("Dave", 9)])
  ,("The Fly",       "David Cronenberg", 1986, [("Fred", 7),("Dave", 4)])
  ]

-- These 2 functions are for the average rating

averageFilm :: Film -> Float
averageFilm (t, d, y, r) = averageFilmRating r

averageFilmRating :: [Rating] -> Float
averageFilmRating rating = fromIntegral ((sum [r | (_,r) <- rating])) / fromIntegral ((length rating))

---- These 2 functions are for the year filtering

displayFilmsYear :: Year -> Database -> String
displayFilmsYear year database = displayFilms (filter (filmYear year) database)

filmYear :: Year -> Film -> Bool
filmYear year (t, c, y, f)
         | year <= y = True
     | otherwise = False 
Run Code Online (Sandbox Code Playgroud)

Lee*_*Lee 5

import Data.List
import Data.Ord

sortByRating :: [Film] -> [Film]
sortByRating = sortBy (flip $ comparing averageFilm)
Run Code Online (Sandbox Code Playgroud)

sortBy允许您使用给定的比较函数对列表进行排序.这个功能有类型

(a -> a -> Ordering)

where Ordering表示第一个参数是否小于,大于或等于第一个参数.

sortBy :: (a -> a -> Ordering) -> [a] -> [a]
Run Code Online (Sandbox Code Playgroud)

对于您的Film列表,您的比较函数因此具有类型Film -> Film -> Ordering.您可以使用以下命令创建此类函数comparing:

comparing :: Ord a => (b -> a) -> (b -> b -> Ordering)
Run Code Online (Sandbox Code Playgroud)

在您的情况下,您需要返回序数值来比较电影.你已经有了这样的功能 - averageFilm.comparing averageFilm因此返回一个功能(Film -> Film -> Ordering),按照评级比较两部电影.

sortBy (comparing averageFilm)将通过评级按升序对列表进行排序,因此要按降序排序,您只需将参数的顺序翻转到比较函数,即flip (comparing averageFilm).