我有一个平面文本文件,格式如下:
ID|COUNT|Desc
1|100|Something
2|100|More
1|15|Whatever
我需要将它加载到Haskell中以便我可以执行一些操作(在GROUP-BY ID和SUM COUNT的情况下)并且我正在寻找方法 - 有一件事我不能使用任何额外的模块/包(这是一个学校项目 - 试图通过内置的任何内容来解决这个问题。)
我正在进行一些研究,发现Text.CSV是一个选项,但我不能真正理解它是如何工作的(无法找到任何例子 - 这是可怕的) - 在我花了很多时间之前想知道这是否是正确的方法 - 任何建议,想法或例子将不胜感激。
请记住,无论如何存储,我都必须以某种方式处理数据。
我现在正在尝试这种方法:
main::IO()
main = do
dbSales <- readFile "la.txt"
let sales = lines dbSales
(result, x, y) <- mapify sales
print result
mapify :: [String] -> Map Int Int
mapify = Prelude.foldr (\s m -> let (id:count:desc) = (splitWhen (=='|') s)
i = read id
c = read count
in insertWith (+) i c m) empty
然而,它抱怨我称之为mapify的行:
Couldn't match type `Map Int' with `IO'
Expected type: IO Int
Actual type: Map Int Int
尝试使用新的输入文件而不确定原因但是如果我使用以下输入错误 -
ID1|ID2|DATE|SUM
0|0|07/13/2014/100
0|1|07/13/2014/101
0|2|07/13/2014/102
1|0|07/13/2014/100
而现在我试图将ID2和SUM分组(而不是上一个例子中的od ID和COUNT):
mapify :: [String] -> Map Int Int
mapify = Prelude.foldr (\s m -> let (id1:id2:date:sum) = (splitWhen (=='|') s)
i = read id1
j = read id2
k = read date
c = read sum
in insertWith (+) j c m) empty
但无论我尝试什么,我都会遇到这样的错误:
Couldn't match type `[Char]' with `Char'
Expected type: String
Actual type: [[Char]]
In the first argument of `read', namely `sum'
In the expression: read sum
In an equation for `c': c = read sum
答案 0 :(得分:1)
mapify :: [String] -> Map Int Int
mapify = foldr (\s m -> let (id:count:desc) = (splitWhen (=='|') s)
i = read id :: Int
c = read count :: Int
in insertWith (+) i c m) empty
我认为这应该是你想要的。它将每个字符串的前两个值读入Ints,然后insertWith将id添加到地图中(如果它不存在),或者增加当前计数(如果不存在)。因为它会因格式不正确的数据而崩溃,所以您可能想要解决这个问题,它需要Data.List.Split
和Data.Map