根据分数拆分学生名单 - haskell
Split list of student according to their mark - haskell
有一个学生列表
data Student = Student {
name :: String,
mark :: Mark
} deriving Show
data Mark = F|E|D|C|B|A deriving (Show, Eq, Ord)
我需要这样拆分它[(mark,[students with this mark])]
我做了这样的东西:
splitToGroups :: [Student] -> [(Mark, [String])]
splitToGroups [] = []
splitToGroups students = foldr funct [] students where
funct student [] = [(mark student,[name student])]
funct student ((x,xs):xss) | mark student == x = ((x,(name student):xs):xss)
| otherwise = (mark student,[name student]):(x,xs):xss
但它工作不正确。也许有人知道怎么做..
如果可以使用标准工具,请不要手动递归。您可以通过排序和分组来做到这一点,但 IMO 更可取的是使用类型来表示您正在构建一个 associative 结果,即从标记到学生的映射。
import qualified Data.Map as Map
splitToGroups :: [Student] -> Map.Map Mark [String]
splitToGroups students = Map.fromListWith (<>)
[ (sMark, [sName])
| Student sName sMark <- students ]
(如果你想要最后一个列表,就用Map.toList
。)
如果您将 Student 视为元组,则您的函数具有此类型:splitToGroups :: [(Mark,String)] -> [(Mark, [String])]
。
所以你需要一个类型为 [(a,b)] -> [(a,[b])]
.
的函数
使用Hoogle:search results
我得到以下功能:
groupSort :: Ord k => [(k, v)] -> [(k, [v])]
collectSndByFst :: Ord a => [(a, b)] -> [(a, [b])]
它们应该可以解决您的问题,请记住导入 link 中列出的模块以使它们正常工作。您应该首先创建一个从 Student -> (Mark, String)
映射的函数。
有一个学生列表
data Student = Student {
name :: String,
mark :: Mark
} deriving Show
data Mark = F|E|D|C|B|A deriving (Show, Eq, Ord)
我需要这样拆分它[(mark,[students with this mark])]
我做了这样的东西:
splitToGroups :: [Student] -> [(Mark, [String])]
splitToGroups [] = []
splitToGroups students = foldr funct [] students where
funct student [] = [(mark student,[name student])]
funct student ((x,xs):xss) | mark student == x = ((x,(name student):xs):xss)
| otherwise = (mark student,[name student]):(x,xs):xss
但它工作不正确。也许有人知道怎么做..
如果可以使用标准工具,请不要手动递归。您可以通过排序和分组来做到这一点,但 IMO 更可取的是使用类型来表示您正在构建一个 associative 结果,即从标记到学生的映射。
import qualified Data.Map as Map
splitToGroups :: [Student] -> Map.Map Mark [String]
splitToGroups students = Map.fromListWith (<>)
[ (sMark, [sName])
| Student sName sMark <- students ]
(如果你想要最后一个列表,就用Map.toList
。)
如果您将 Student 视为元组,则您的函数具有此类型:splitToGroups :: [(Mark,String)] -> [(Mark, [String])]
。
所以你需要一个类型为 [(a,b)] -> [(a,[b])]
.
使用Hoogle:search results
我得到以下功能:
groupSort :: Ord k => [(k, v)] -> [(k, [v])]
collectSndByFst :: Ord a => [(a, b)] -> [(a, [b])]
它们应该可以解决您的问题,请记住导入 link 中列出的模块以使它们正常工作。您应该首先创建一个从 Student -> (Mark, String)
映射的函数。