繁体   English   中英

Haskell函数对输入列表进行排序,然后对排序后的列表进行处理

[英]Haskell function sort input list then do stuff with sorted list

简洁版本:

我想对一个列表进行排序,然后对该排序后的列表执行操作,以过滤/提取数据以形成一个新列表,所有这些功能都是一样的。

长版:

我正在使用这些课程自学Haskell。 我目前正在做作业2练习5。

我需要编写一个函数whatWentWrong ,该函数采用whatWentWrong未排序列表并返回字符串列表。 字符串是用Error构造的LogMessages的String部分,其中Error代码大于50。它们应该按LogMessage的TimeStamp部分排序。

我有一个针对whatWentWrong编写的函数,该函数可以工作,但确实非常慢(您会明白为什么)。

whatWentWrong :: [LogMessage] -> [String]
whatWentWrong [] = []
whatWentWrong ys@((LogMessage (Error code) _ msg):xs)
    | ys /= inOrder (build ys)
      = whatWentWrong (inOrder (build ys))
    | code > 50
      = [msg] ++ whatWentWrong xs
    | otherwise
      = whatWentWrong xs
whatWentWrong (_:xs) = [] ++ whatWentWrong xs

inOrder (build x)函数将返回inOrder (build x)的排序版本(其中x是LogMessages列表)。 显然,我必须先对列表进行排序,然后再使用whatWentWrong处理它,或者必须过滤掉所有不相关的消息(不是错误或错误代码不超过50的消息),然后进行排序,然后抓取每个字符串。

如果我不遵循此示例,则可以定义另一个函数或其他内容,或者仅发送一个已经排序的列表whatWentWrong 但我想有某种理由这样做(我不知道)。

无论如何,我所做的事情以及程序为何如此缓慢的原因是: ys /= inOrder (build ys) 每次遇到与Error模式匹配的LogMessage时,都会检查LogMessage列表是否已排序,甚至但是,在第一次检查失败后,该列表将被排序。

那是我唯一想到的方法。 确实,我想对它进行一次排序,但是我不知道如何使该函数使用我的排序函数对列表进行排序,然后再也不执行该步骤。 我显然没有正确地考虑这个问题,我们将不胜感激。 谢谢。

您实际上只需要单行列表理解:

whatWentWrong xs = [ msg | (LogMessage (Error code) _ msg) <- inOrder (build xs), code > 50]

如果要对列表进行排序以查看列表是否已排序,则也可以直接在已排序的列表上工作。 完成此操作后,列表推导将自动过滤掉与模式不匹配的元素,而code > 50过滤其余部分。


如果您想通过练习来修复当前代码,则只需定义一个帮助程序函数(假定其输入已排序)即可。

whatWentWrong :: [LogMessage] -> [String]
whatWentWrong ys = www (inOrder (build ys))
                   where www [] = []
                         www ((LogMessage (Error code) _ msg):xs) | code > 50 = msg : www xs
                                                                  | otherwise = www xs
                         www (_:xs) = www xs

但是,您应该认识到wwwmapfilter的组合。

whatWentWrong ys = map f $ filter p (inOrder (build ys))
                   where p (LogMessage (Error code) _ _) = code > 50
                         p _ = False
                         f (LogMessage _ _ msg) = msg

或者,以无点样式

whatWentWrong = map f . filter p . inOrder . build
                where p (LogMessage (Error code) _ _) = code > 50
                      p _ = False
                      f (LogMessage _ _ msg) = msg

暂无
暂无

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

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