与任何UI任务一样,格式化输出通常变得异常棘手。这种情况也不例外。
的想法是这样的:
- 图出来有多宽表中的“细胞”应该是。
- 通过将转换为字符串并填充到单元格宽度的数字连接在一起来构建每一行。
- 预先安排第一行。
- 连接将它们与换行符分隔开的所有行。
首先,让我们看看我们如何计算出“单元格”的宽度。表中最宽的数字是多少?假设n
和m
均为正数,显然最宽数字为n*m
。所以,我们可以计算出电池的这样的宽度:
let cellWidth = (n*m) |> string |> String.length
类似地,第一个(最左边的)列将是一样宽于它的最大数目,这是n
:
let firstColWidth = n |> string |> String.length
现在
,让我们做自己,会采取一些和左垫它的空间到所需宽度的函数:
let pad totalWidth (value: obj) =
let s = string value
if s.Length >= totalWidth then s
else (String.replicate (totalWidth-s.Length) " ") + s
此功能容易遵循:如果字符串ALR超过最大限度,只需返回它,否则预先加上(totalWidth-s.Length)
空格。
有了这些功能,我们可以格式化我们的网格中的一行:
let formatRow rowIdx =
let cells = [for colIdx in 0..m-1 -> grid.[rowIdx,colIdx] |> pad cellWidth] // Each cell in this row padded to `cellWidth`
let firstCol = (rowIdx+1) |> pad firstColWidth // Leftmost column - just the row index itself padded to `firstColWidth`
let wholeRow = firstCol :: cells // Whole row consists of the leftmost column plus subsequent cells
String.concat " " wholeRow
同样,格式化顶端行:
let firstRow =
let cols = [for col in 1..m -> col |> pad cellWidth]
let firstCol = " " |> pad firstColWidth
let wholeRow = firstCol :: cols
String.concat " " wholeRow
看看这些功能如何相似:唯一的区别是grid.[rowIdx,colIdx]
与col
。我们为什么不概括这一点?
let formatRowWith firstCell getCell =
let cells = [for colIdx in 0..m-1 -> getCell colIdx |> pad cellWidth]
let firstCol = firstCell |> pad firstColWidth
let wholeRow = firstCol :: cells
String.concat " " wholeRow
let formatRow rowIdx = formatRowWith (rowIdx+1) (fun c -> grid.[rowIdx,c])
let firstRow = formatRowWith " " (fun c -> c+1)
最后,格式每一行,前面加上第一,并连接它们放在一起:
let rows = [0..n-1] |> List.map formatRow
let allRows = firstRow :: rows
String.concat "\n" allRows
最终代码:
let formatGrid (grid:_[,]) =
let n, m = grid.GetLength 0, grid.GetLength 1
let cellWidth = (n*m) |> string |> String.length
let firstColWidth = n |> string |> String.length
let pad totalWidth (value: obj) =
let s = string value
if s.Length >= totalWidth then s
else (String.replicate (totalWidth-s.Length) " ") + s
let formatRowWith firstCell getCell =
let cells = [for colIdx in 0..m-1 -> getCell colIdx |> pad cellWidth]
let firstCol = firstCell |> pad firstColWidth
let wholeRow = firstCol :: cells
String.concat " " wholeRow
let formatRow rowIdx = formatRowWith (rowIdx+1) (fun c -> grid.[rowIdx,c])
let firstRow = formatRowWith " " id
let rows = [0..n-1] |> List.map formatRow
let allRows = firstRow :: rows
String.concat "\n" allRows
谢谢你,这是完美工作:)如何格式化表格有何建议? – NaNaNiii