2017-04-20 63 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每隔一对行之间的分隔符的副本。