2017-04-20 61 views
2
type Field = String 
type Row = [Field] 
type Column = [Field] 
type Table = [Row] 



print_line :: [Int] -> String 
print_line lstcolumnwidths = case lstcolumnwidths of 
    []  -> "+" 
    n:ns -> '+' :replicate n '-' ++ print_line ns 

此代碼創建一條線,例如:與輸入[3,6],將返回「+ --- + ------ +」如何編寫結合以下所有功能以達到所需輸出的功能

print_field :: Int -> Field -> String 
print_field columnwidth fieldcont 
    |isNum fieldcont  = replicate (columnwidth - length fieldcont) ' ' ++ fieldcont 
    |otherwise    = fieldcont ++ replicate (columnwidth - length fieldcont) ' ' 

isNum :: String -> Bool 
isNum s = case s of 
    []  -> True 
    x:xs -> isDigit x && isNum xs 

此代碼格式化字段例如輸入5「艾美」返回「艾米」和 爲輸入端5 「78」 返回 「78」

print_row :: [Int] -> Row -> String 
print_row lstcolumnwidths lstfieldcont = convertString (zipWith print_field 
lstcolumnwidths lstfieldcont) 


convertString :: [String] -> String  
convertString x = case x of 
    []  -> "|" 
    x:xs -> '|' : x ++ convertString xs 

此代碼返回一個格式化的行例如輸入並[5,4] [ 「托米」, 「20」]返回 「|托米| 20 |」

print_table :: Table -> [String] 

我想寫一個函數爲此需要一個表並返回一個字段列表。 的投入將是

[["first","last","gender","age"],["Patricia","Davies","female","20"], 
["Paul","Dowden","male","19"],["John","Doe","male","24"], 
["David","Barker","male","21"],["Eve","Lee","female","23"], 
["Mary","Hester","female","21"]] 

,我想輸出是

["+--------+------+------+---+","|FIRST |LAST |GENDER|AGE","|Paul  
|Dowden |male | 19","+--------+------+------+---+","|David |Barker |male | 21"...etc ] 

如何編寫,結合了功能的任何提示所有以前達成,這將是有幫助的。

我也有一個功能

convert :: String -> String 
convert list = case list of 
    []   -> [] 
    c:cs 
    |isUpper c -> c: convert cs 
    |otherwise -> toUpper c : convert cs 

它是用於第一個字段轉換爲大寫。

回答

0

那麼,你幾乎一切就位。首先,您似乎缺少的是計算列寬的方法。您可以定義:

colWidth :: Column -> Int 
colWidth fields = maximum (map length fields) 

計算單個列的寬度。

然後,您可以使用transposeData.List移調你的表從行的列表爲列的列表,並且對這些列映射colWidth

colWidths :: Table -> [Int] 
colWidths table = map colWidth (transpose table) 

其次,你需要的print_table定義,這是短期,因爲你已經把所有的辛勤工作所:

print_table :: Table -> [String] 
print_table table = 
    let wdths = colWidths table    -- the column widths 
     separator = print_line wdths   -- the row-by-row separator 
     heading:body = map (print_row wdths) table -- the rows 
     heading' = convert heading   -- the heading in upper-case 
    in [separator] ++ intersperse separator (heading':body) ++ [separator] 

唯一的「絕招」這裏使用intersperse(也Data.List)到STI ck每隔一對行之間的分隔符的副本。