2014-10-01 60 views
1

我非常喜歡哈斯克爾。我有一些數據嘎吱嘎吱做,並認爲我會在哈斯克爾做。實質上,我將多個文件的內容轉換並將新輸出存儲在一個文件中。每個文件都被轉換成一個數字列表。然後我需要在保存輸出前轉置列表。我有以下幾點:加載和轉換來自多個文件的數據

main = do 
    allFiles <- getDirectoryContents inputDir 
    contents <- readFile (validFiles allFiles !! 1) 
    let activeCompanies = getMonthRow contents 
    print $ activeCompanies 

getMonthRow :: String -> [String] 
-- returns the needed data from the file 

validFiles :: [String] -> [String] 
-- removes invalid files from the list of filenames 

這工作,並activeCompanies包含數字的列表,因爲它應該。作爲證明,我只拿到validFiles中的第一個文件。我想要做的是從所有文件中讀取數據並將它們存儲在一個大列表中。這將是這樣的

[["1","2","3"],["2","3","4"],["4","5","6"]] 
where each sublist is the `activeCompanies` list I retrieved from one file 

這樣做的原因是,我需要將它存儲所有輸出文件(即多個輸入文件,一個輸出文件)之前,轉置數據。

我該如何做到這一點?我想到的是,對於每個文件,我可以將列表寫入輸出文件,每行一個元素,然後在讀取輸入文件時更新輸出文件中的每一行。然而,在這一點上,我全都耳熟能詳。

回答

3

我認爲這應該工作。它讀取所有文件和transposesgetMonthRow映射的內容。

import Data.List 

main = do 
    allFiles <- getDirectoryContents inputDir 
    contents <- mapM readFile $ validFiles allFiles 
    print $ transpose $ map getMonthRow contents 
+0

最後一行應該是'print $ transpose $ map getMonthRow contents',但除此之外,這工作得非常好。 – Gevious 2014-10-02 06:07:51

+1

這不*首先*讀取所有文件。 'readFile'是延遲輸入。如果'getMonthRow'也足夠懶惰,只要你沒有用完打開的文件描述符,這應該能夠在寫入輸出的同時並行地流式傳輸所有文件。這可能是你想要的。 – 2014-10-02 09:09:18

2

試試這個。它遍歷所有有效的文件,讀取它們,並應用getMonthRow

import Control.Monad 

main = do 
    allFiles <- getDirectoryContents inputDir 
    bigList <- forM (validFiles allFiles) (fmap getMonthRow . readFile) 
    print bigList 

更詳細地,forM在這種情況下需要[String]類型的列表,以及String -> IO [String]類型的函數。其結果使得bigList a [[String]]

fmap getMonthRow . readFile片段相當於輔助功能

readMonthRow :: String -> IO [String] 
readMonthRow s = do 
    wholeFile <- readFile s 
    return (getMonthRow wholeFile)