在Xcode控制台中生成等宽列的表格

5

以下是我用来检查计算的一段代码,我只是将这些值写入Xcode控制台。每个数组都声明了下面显示的值。

var water_deficit: [Int] = []

该程序计算了水分亏缺的数值,并将其添加到此列表中(未显示计算过程)。
let months = ["January","Feburary","March","April","May","June","July","August","September","October","November","December"]
let rainfall = [38,94,142,149,236,305,202,82,139,222,178,103]
let raindays = [3,6,8,7,12,16,10,8,12,14,11,7]
for i in 0...11 {
    println("\(months[i]) \t \(rainfall[i]) \t \(raindays[i]) \t \(water_deficit[i])")
}

控制台上显示的输出:
Month    Rainfall    Raindays    Water Deficit
January      38      3   38
Feburary     94      6   -18
March    142     8   -8
April    149     7   -1
May      236     12      116
June     305     16      301
July     202     10      202
August   82      8   82
September    139     12      101
October      222     14      203
November     178     11      208
December     103     7   103

如您所见,由于单词/数字的长度不同,导致列之间偏移。为了避免这个问题,我需要做什么才能生成特定宽度的列?


1
尝试这个链接: http://stackoverflow.com/questions/28138689/format-println-output-in-a-table - Apple-and-Oranges
@Apple-and-Oranges,感谢您提供那个问题的链接,这为我提供了一种找到数据最大长度的方法,但是它说“然后填充这些字符串”。我是编程新手,不知道这是什么意思,也不知道如何做。您知道怎么做吗? - Jack Hayton
你能展示一下降雨量、雨天数等的声明吗?它们是整型数组还是字符串数组? - Mario Zannone
@MarioZannone,我已经编辑了问题,将声明与程序中完全相同。我认为months是String类型,其余的数组都是Int类型。希望这可以帮助。 - Jack Hayton
5个回答

6

试试这个:

for i in 0...11 {
  let month = (months[i] as NSString).UTF8String
  println(String(format:"%-10s %10d %10d %10d",  month, 
                 rainfall[i], raindays[i], water_deficit[i]))
}

有关格式和格式说明符的详细信息,请参见此处此处

let month = (months[i] as NSString).UTF8String中,我正在将字符串转换为C字符串:在C字符串的格式说明符中指定长度非常容易,但是我不知道如何在字符串的格式说明符中指定长度(我猜这是不可能的)。


1
谢谢你,这很有效!但是我不理解它,能否请您解释一下.UTF8String是什么意思?%-10s和%10d是做什么用的?如果这看起来很明显,那是因为我很新手,之前没有见过。谢谢! - Jack Hayton
是的。我刚刚添加了一些解释和参考资料。 - Mario Zannone

2

技巧在于根据你想要字符串是右对齐还是左对齐,计算正确的填充量,向字符串单元的左侧或右侧添加填充。这里是一个快速实现。(Swift 2.0,Xcode 7 beta3)。

  let headings = ["Month    ", "Rainfall", "RainDays", "Water Deficit"]

let months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]

let rainFalls = [38, 94, 142,149,236,305,202, 82, 139, 222, 178, 103]
let rainyDays = [3, 6, 8,7,12,16,10, 8, 12, 14, 11, 7]
let waterDeficits = [38, -18, -8,-1,116,301,202, 82, 101, 203, 208, 103]


func getRightJustifiedStringRepFor(number: Int, refString:String) -> String
{
    let length = refString.utf8.count
    let stringRep = String(number)

    var paddedStringRep : String = ""

    //Build necessary padding
    for  var i = 0 ; i <  (length - stringRep.utf8.count) ; i++
    {
        paddedStringRep += " "
    }

    paddedStringRep += stringRep

    return paddedStringRep
}


let headingsToDisplay = headings.reduce(""){

    (var accummulated : String, item: String) -> String in
    return accummulated  + item +  "\t\t\t"

}

print(headingsToDisplay)

//Get proper aligned months with forward padding as we want them left aligned
let leftJustifiedMonths = months.map{
    (var item: String) -> String in
    let paddingsNeeded = 9 - item.utf8.count  //9 is the  length of lengthy month name
    for var i = 0 ; i < paddingsNeeded ; i++
    {
        item += " "
    }
    return item
}

print("\n")

for i in 0...11
{
    print(leftJustifiedMonths[i], appendNewline:false)
    print("\t\t\t", appendNewline:false)
    print( (getRightJustifiedStringRepFor(rainFalls[i], refString: "Rainfall")), appendNewline:false)
    print("\t\t\t", appendNewline:false)
    print( (getRightJustifiedStringRepFor(rainyDays[i], refString: "RainDays")),appendNewline:false)
    print("\t\t\t", appendNewline:false)
    print( (getRightJustifiedStringRepFor(waterDeficits[i], refString: "Water Deficit")),appendNewline:false)

    print("\n")

}

这将输出:

这里输入图像描述


谢谢您的帖子,我尝试将其复制并粘贴到新的 playground 中,但代码中有几个错误。第一个错误出现在命令“variablename.utf8.count”中,显示错误:String.UTF8View 没有名为 count 的成员(出现两次)。第二个错误是 for 循环中的第一个 print 语句。错误是:“找不到接受...的 print 重载”。我是编程新手,所以不知道这些错误是什么意思或如何修复它们。 - Jack Hayton
哦,忘了提一下,这是Swift 2.0,Xcode 7 beta3。 - Shripada

1
for i in 0...11 {
print(months[i])
countElements(months[i]) > 4 ? print("\t\t") : print("\t\t\t")

print(rainfall[i])
countElements(String(rainfall[i])) > 4 ? print("\t\t") : print("\t\t\t")

print(raindays[i])
countElements(String(raindays[i])) > 4 ? print("\t\t") : print("\t\t\t")

print(water_deficit[i])
print("\n")

}


如果看起来愚蠢,但它能够工作,那就不算愚蠢。 - L33MUR

0
// This basically months max string count calculation and how many spaces needed to print
        var maxMountStringCount = 0
        let months = ["January", "Feburary", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
        months.forEach({ (month) in
            if month.count > maxMountStringCount {
                maxMountStringCount = month.count
            }
        })
        months.forEach({ (month) in
            let keySpace = String(repeating: " ", count: maxMountStringCount - month.count)
            print("\t\t\(month)\(keySpace) :\t\(month) ")
        })

控制台预览是:

⎩   January   : January 
⎩   Feburary  : Feburary 
⎩   March     : March 
⎩   April     : April 
⎩   May       : May 
⎩   June      : June 
⎩   July      : July 
⎩   August    : August 
⎩   September : September 
⎩   October   : October 
⎩   November  : November 
⎩   December  : December 

很简单。您可以根据自己的需求进行开发。


0

这是因为您的字符串长度和变量长度不匹配,\t导致字符串长度中的制表符与行中的制表符不匹配。

所以有两种方法可以解决这个问题:

  1. 最简单的方法 -> 只需使所有月份名称具有相同的长度即可轻松消除不匹配

    let months : [String] = ["jan","feb","mar","apr","may","june","july","aug","sept","oct","nov","dec"]

  2. 将您的变量格式化为以下格式:

    let nf = NSNumberFormatter() nf.numberStyle = NSNumberFormatterStyle.DecimalStyle


1
我知道这是个问题,只是不知道如何解决!更改月份的名称是可行的,但我觉得那并不是解决问题,只是掩盖问题而已。此外,我想知道如何在表格中打印的值发生变化的情况下(根据用户输入),例如,在某种情况下,数字可能显示为101(3个字符)。如果用户在程序开头输入不同的值,那么同样的数字可能会显示为1000(4个字符),从而出现相同的问题。必须有一种方法可以创建具有给定宽度的列。 - Jack Hayton
对于 i 在 0 到 11 的范围内 { 打印(months[i]) countElements(months[i]) > 4 ? print("\t\t") : print("\t\t\t")打印(rainfall[i]) countElements(String(rainfall[i])) > 4 ? print("\t\t") : print("\t\t\t") 打印(raindays[i]) countElements(String(raindays[i])) > 4 ? print("\t\t") : print("\t\t\t") 打印(water_deficit[i]) print("\n")} - Sandeep Jangir
只需复制粘贴这段代码@JackHayton...它将帮助你解决所有可能的情况 :) - Sandeep Jangir
我已经复制了代码,但它没有起作用。最初程序要求我在连续命令之间添加分号(;),即使这样做了,它仍然不能工作。如果您知道一种我可以理解并且可以在任何情况下应用的解决方法,我更愿意选择这个方法。 - Jack Hayton
我正在上传另一个答案以获得更好的查看体验 :) - Sandeep Jangir

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接