Performance Haskell';s Data.Map可以用于元组列表吗?
最近我需要比较两组历史数据。因为有时其中一个数据集缺少一两天,我想说得更准确一些,所以我决定创建一个所有可能日期的列表和两个元组列表,其中包含日期和属于这两个数据集的相应值。然后我将后面的列表更改为Performance Haskell';s Data.Map可以用于元组列表吗?,performance,haskell,Performance,Haskell,最近我需要比较两组历史数据。因为有时其中一个数据集缺少一两天,我想说得更准确一些,所以我决定创建一个所有可能日期的列表和两个元组列表,其中包含日期和属于这两个数据集的相应值。然后我将后面的列表更改为Maps,以改进日期查找 其想法是尝试从映射ped列表中的完整日期列表中查找每个日期,并创建一个(日期,值1,值2)的“三元组”列表,其中仅包含两个数据集都有日期和值的日期。然后我可以将它们写入一个文件,并对它们进行适当的比较 不要介意代码,它只是为了更好的度量而包含的 下面是代码(它根本不是最优的,
Map
s,以改进日期查找
其想法是尝试从映射
ped列表中的完整日期列表中查找每个日期,并创建一个(日期,值1,值2)
的“三元组”列表,其中仅包含两个数据集都有日期和值的日期。然后我可以将它们写入一个文件,并对它们进行适当的比较
不要介意代码,它只是为了更好的度量而包含的
下面是代码(它根本不是最优的,但对于这个小任务,它做得很好):
导入符合条件的数据。映射为M
导入数据列表(转置)
导入数据。可能(fromJust)
main=do
dts M.Map字符串->M.Map字符串->可能(字符串,字符串,字符串)
getTrips日期映射1映射2
|is1/=Nothing&&is2/=Nothing=Just(日期,fromJust是1,fromJust是2)
|否则=没有
哪里
is1=M.lookup日期映射1
is2=M.lookup日期映射2
TL;DR:代码起作用了(尽管我很乐意听到一些意见/建议),但我有一些问题:
- 只有大约2000个日期,因此我不太关心性能(您可以看到我到处都在使用
s);当时使用String
是不是太过分了什么时候应该首选Data.Map
而不是元组列表?数据.Map
是从Map
s的元组中创建的-为了使平衡和查找正常工作,键应该始终是数字键还是可以?String
Map
可能是一个好主意。也许在你的情况下,如果你的数据已经被订购了,你可以这样做
union [] _ = []
union _ [] = []
union xss@((dx,vx):xs) yss@((dy,vy):ys) =
case compare dx dy of
EQ -> (dx, vx, vy) : union xs ys
GT -> union xss ys
LT -> union xs yss
该映射是从字符串的元组创建的-它是好的还是应该
键始终为数字,以便平衡和查找工作
适当地
否,如果您的代码类型检查,您的
映射将正常工作(w/r/t您定义的Ord
实例)。但正如C.A.McCann所建议的,如果您的键是列表,A可能更合适,特别是如果键前缀之间有很多重叠(看看列表上的Ord
实例是如何实现的,想象一下插入键“abcdx”、“abcdy”和“abcdz”必须进行的操作数量进入一个Map
与一个trie结构来说服你自己)。如果你使用元组列表作为键值映射,你最好使用Data.Map
。键可以是任何Ord
类型,它可以很好地工作,但是对于更具体的类型,可能会有比数据更好的东西。Map
可以替代,比如一些trie风格。我想你可以说这是一个键值情况;我想知道在一般情况下,当人们必须使用某种索引来搜索值时,总是使用Map
或其他特殊类型而不是简单的元组列表是否被认为是一种良好的做法,即使问题不大——或者更确切地说,当需要映射时。当需要映射时,实际上只能根据分析和程序的特定需求来回答。这就是说,我唯一会使用元组列表的时候是我正在做一些数据。Map
和朋友不支持的事情,比如搜索任一组件(即双向多重映射)。我非常喜欢你的工会提案;由于数据已经被分类,我完全喜欢这个简单而聪明的解决方案,而不是“好吧,它起作用”的解决方案。关于在这种情况下考虑trie的建议非常恰当,因为日期字符串非常相似。
union [] _ = []
union _ [] = []
union xss@((dx,vx):xs) yss@((dy,vy):ys) =
case compare dx dy of
EQ -> (dx, vx, vy) : union xs ys
GT -> union xss ys
LT -> union xs yss