合并N个列表,跟踪重复项并按日期排序的最高效方法

时间:2014-03-29 09:40:57

标签: list sorting haskell merge grouping

我是Haskell的新手,我想知道合并任意数量项目的任意数量的列表的最有效方法。这是示例数据:

LIST 1: steve
2014-01-20 | cookies  | steve

LIST 2: chris
2014-02-05 | cookies  | chris

LIST 3: mark
2014-09-30 | brownies | mark
2014-03-30 | candy    | mark
2014-05-12 | pie      | mark

LIST 4: anthony
2014-05-18 | cookies  | anthony
2013-12-25 | fudge    | anthony

LIST 5: andy
2014-10-04 | cookies  | andy

LIST 7: john
2014-06-19 | pie      | john


RESULTING LIST
2014-10-04 | cookies  | andy chris steve anthony
2014-09-30 | brownies | mark
2014-06-19 | pie      | john mark
2014-03-30 | candy    | mark
2013-12-25 | fudge    | anthony

请注意,这些列表都是以人为本,可能会或可能不会按日期排序,结果需要合并先前的列表,分组并创建一个列表,其中甜点是唯一的,但有一个组成人员列表吃了它,按时间顺序按时间顺序排序。

1 个答案:

答案 0 :(得分:1)

解决问题的最佳方式是什么,在大多数情况下,无论是在haskell还是在我认为的任何其他编程语言中都无法回答。

更好的方法是考虑,如何解决这个问题(根本),并在脑海中保留一些原则。

  • 可测试性
  • 抽象和表达
  • 可维护性
  • 可读性
  • 性能

也许我已经忘记了一些事情,但是对于你的问题,我想给出一个提示列表

如果我提前知道所有项目和名称,我会使用代数数据类型来模拟这种情况

data Name  = Mark | Chris ...
           deriving (Ord,Eq,Show)
data Items = Pie | Cookies ...
           deriving (Ord,Eq,Show)

如果我还不知道haskell如何表示日期数据类型,我可以使用普通的String对此进行建模,或者我会使用hoogle查看是否已存在日期内容。

> hoogle date
...
Data.Time.Calendar...
...

所以我认为Data.Time.Calendar模块似乎是一个不错的选择,我会查看其文档,可以找到online或者如果你在本地安装软件包,你可以使用haddock来生成它来自源文件。

接下来我要做的是模拟“数据库”,当然存在库以使用sqly stuff或acid-state数据库使用代数数据类型而不是数据库后端。但是为了更好地掌握haskell,我会尝试重新发明轮子一次并使用一个tupel列表,或者一个类似于字典的集合,它位于haskell中,名为Map。但是使用Map之一必须要小心并进行限定导入,因为大多数提供的函数都会导致名称与标准库中的函数冲突(Prelude)。

import qualified Map as M

并建模我的数据库我会使用Items作为键和日期元组和名称列表作为值,因为我想知道这是我的数据库我会为它提供类型别名。

type DB = M.Map Item (Date, [Name])

为了解决这个问题,我将再次浏览Map文档,并很高兴找到函数insertWithemptytoList。对于insertWith函数,我会想到max和list cons (:)函数的混合来创建新条目。 为了更好地感受整个事情,我会启动ghciimport qualified Data.Map as M,并使用M.Map String (String,[Int])或其他一些例子来愚弄我们的数据,并在第一次近似中建模。

对于结果我必须按日期排序我的地图的toList,这只是一个小问题。我toList myDb的类型为[(Item,(Date,[Name]))],因此fst.sndsortBy排序可能会产生预期结果。

在我做了这么多之后,我会休息并阅读一些关于解析器的内容 - 将我的所有文件都放在我的程序的上下文中。搜索引擎对你最不信任的搜索将会出现一些值得阅读的文章(Parser Parsec Haskell)。 如果所有这些都太复杂了,我会回去并将我的所有类型更改为Strings,并希望在我有时间再次阅读解析器之前我不会有任何类型; - )。

对于中间步骤中的任何问题,此处的人员将很乐意为您提供帮助,假设您提供具体的问题/问题描述。

如果所有这些都不够高效,那么haskell提供的分析工具足以帮助我,但这是我最后一个需要解决的问题。