'Generating a table with columns of equal width (viewed on the console in Xcode)
This is a piece of code that I am using to check my calculations, I am simply writing out these values into the console in Xcode. Each of the arrays is declared with the values that are shown below.
var water_deficit: [Int] = []
The program calculates values for water deficit and appends them into this list (the calculations are not shown)
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])")
}
The output as shown on the console:
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
As you can see, because the length of the words/numbers are different, the columns are offset. What do I need to do to generate columns of a specific width to avoid this problem?
Solution 1:[1]
The trick is to compute right paddings to the left or to the right of a string unit depending on if you want the string to be right or left justified. Here is a quick implementation. (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")
}
This outputs:
Solution 2:[2]
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")
}
Solution 3:[3]
This is happing because your string length and your variable length are mismatching and \t that cause tab in line tab from the string length.
So there are two ways to stop this :
Simplest way -> just make all months name in a same length this will remove the mismatch very easily
let months : [String] = ["jan","feb","mar","apr","may","june","july","aug","sept","oct","nov","dec"]
make your variable in such a format like this:
let nf = NSNumberFormatter() nf.numberStyle = NSNumberFormatterStyle.DecimalStyle
Solution 4:[4]
// 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) ")
})
Console Preview is;
? January : January
? Feburary : Feburary
? March : March
? April : April
? May : May
? June : June
? July : July
? August : August
? September : September
? October : October
? November : November
? December : December
It's simple. You can Develop it up to your needs.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Sandeep Jangir |
| Solution 3 | Sandeep Jangir |
| Solution 4 | Zezeron |

