![](/img/trans.png)
[英]Check a list if sorted in ascending or descending or not sorted in 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
但是,您应该认识到www
是map
和filter
的组合。
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.