# Display 2d array as ASCII table

The task is to display ascii table for a given array.

### Input

The input is an 2D matrix. The matrix's row length is same with the length of an array. Alternatively, you can take input of an 2D matrix with the first row is a header. The outer dimension is the row.

Example Input:

[["License","2008-05-08","2009-03-11","2011-11-22","2013-08-12","2015-11-19"],["GPLv2","58.69%","52.2%","42.5%","33%","23%"],["GPLv3","1.64%","4.15%","6.5%","12%","9%"],["LGPL 2.1","11.39%","9.84%","?","6%","5%"],["LGPL 3.0","? (<0.64%)","0.37%","?","3%","2%"],["GPL family together","71.72% (+ <0.64%)","66.56%","?","54%","39%"]]


### Output

The output of a table looks like below.

+---------------------+-------------------+------------+------------+------------+------------+
| License             | 2008-05-08        | 2009-03-11 | 2011-11-22 | 2013-08-12 | 2015-11-19 |
+---------------------+-------------------+------------+------------+------------+------------+
| GPLv2               | 58.69%            | 52.2%      | 42.5%      | 33%        | 23%        |
| GPLv3               | 1.64%             | 4.15%      | 6.5%       | 12%        | 9%         |
| LGPL 2.1            | 11.39%            | 9.84%      | ?          | 6%         | 5%         |
| LGPL 3.0            | ? (<0.64%)        | 0.37%      | ?          | 3%         | 2%         |
| GPL family together | 71.72% (+ <0.64%) | 66.56%     | ?          | 54%        | 39%        |
+---------------------+-------------------+------------+------------+------------+------------+


Each cell has exactly one space on the left and at least one space on the right, padded until the bars aligned. However, at least one cell has only one space on its right.

### Test cases

Input:
[["Hello", "World", "!!!"],["aa", "bbbbbbbbb", "CcC"], ["Pyth",  "CJam", "GolfScript"]]

Output:
+-------+-----------+------------+
| Hello | World     | !!!        |
+-------+-----------+------------+
| aa    | bbbbbbbbb | CcC        |
| Pyth  | CJam      | GolfScript |
+-------+-----------+------------+


### Example submission

function ascii_table(array, header) {
var lengths = array[0].map(function(_, i) {
var col = array.map(function(row) {
if (row[i] != undefined) {
return row[i].length;
} else {
return 0;
}
});
return Math.max.apply(Math, col);
});
array = array.map(function(row) {
return '| ' + row.map(function(item, i) {
var size = item.length;
if (size < lengths[i]) {
item += new Array(lengths[i]-size+1).join(' ');
}
return item;
}).join(' | ') + ' |';
});
var sep = '+' + lengths.map(function(length) {
return new Array(length+3).join('-');
}).join('+') + '+';
return sep + '\n' + array[0] + '\n' + sep + '\n' +
array.slice(1).join('\n') + '\n' + sep;
} else {
return sep + '\n' + array.join('\n') + '\n' + sep;
}
}


This is , so the submission with the least amount of bytes wins!

• Looks like first answerer. Please, do not use example-of-solution. Jan 17 '16 at 9:21
• @ChristianIrwan deleted. Jan 17 '16 at 9:22
• Don't delete, I will try to figure out the challenge. Jan 17 '16 at 9:23
• You have enough reputation to be on chat. Do you think we should talk about improving this on Chat? (It seems like it will become extended discussion.) Jan 17 '16 at 9:25
• If we want to take input as a single string instead of an array, does it have to be in the exact same format as the example inputs? If so, will there ever be any escaped characters (or will there ever be quotes in the input)? Can we also assume that there are no brackets or commas in the input other than the array delimiters? What about vertical bars? In general, what are the valid characters that can make up the strings in the table?
– Doorknob
Jan 17 '16 at 16:07

## vim, 139138 134

$x0xqq%ls<cr><esc>@qq@q:se nosol|%s/,/\t/g|%s/]/\t./|%!column -t -s'<C-v><Tab>'<cr>qwf";;h<C-v>GI|<esc>@wq@wll<C-v>Gls|<esc>0<C-v>Gs| <esc>:%s/"//g<cr>Yp:s/[^|]/-/g|s/|/+/g<cr>YggpkP  Accepts input in the form shown in the test cases. May or may not be valid, as this relies on the input string never containing any ", ,, ], or | characters. If the input has to be able to contain ]s, then :%s/]/\t./<cr> can be replaced with qe$s<Tab>.<esc>j@eq@e for 2 extra chars. There is no easy way to allow ",| in the input.

Must be run in a Unix environment, as it relies on the column command line tool.

Slightly outdated explanation (by one revision, but that was just a bit of rearranging):

:se nosol<cr>    we need this later: G in visual block shouldn't go to BOL
$x0x delete the surrounding pair of brackets qq record a macro %ls<cr><esc> put each element of the big array on its own line @qq recurse @q play back the macro until EOF :%s/,/\t/g<cr> replace all remaining commas with tabs :%s/]/\t./<cr> replace the ] at the end of lines with tabs and a dot we need this for the line at the right edge of the table :%!column -t run the whole file through column' on tabs -s'<C-v><Tab> '<cr> qw record another macro f";; go forward 3 "s--that is, to the next "column" h go back to the middle of the column <C-v>GI|<esc> insert a line behind the cursor from top to bottom @wq recurse @w play back until EOF ll move right before the line of dots we added earlier <C-v>Gl select the dots s|<esc> replace with a line (top to bottom) 0<C-v>G select all the opening brackets s| <esc> again, (the leftmost) line :%s/"//g<cr> kill all the quotes around the data Yp duplicate bottom line :s/[^|]/-/g<cr> replace everything that's not a line with a dash :s/|/+/g<cr> now replace the lines with plus signs YggpkP put the separators before and after the first line  Thanks smpl for a byte! • You can save a byte by replacing :set with :se. Jan 17 '16 at 20:27 # JavaScript (ES6), 210 212 219 Edit 2 bytes saved thx @Neil a=>(J=(m,j)=>j+m.join(j)+j,a.map(r=>r.map((c,i)=>s[i]>(l=c.length)?0:s[i]=l),s=[]),t=J(s.map(n=>'-'.repeat(n+2)),'+'),z=a.map(r=>J(r.map((c,i)=>' '+c+' '.repeat(s[i]+1-c.length)),'|')),z[0]+= +t,t+J(z, )+t)  TEST F=a=>( J=(m,j)=>j+m.join(j)+j, a.map(r=>r.map((c,i)=>s[i]>(l=c.length)?0:s[i]=l),s=[]), t=J(s.map(n=>'-'.repeat(n+2)),'+'), z=a.map(r=>J(r.map((c,i)=>' '+c+' '.repeat(s[i]+1-c.length)),'|')), z[0]+='\n'+t, t+J(z,'\n')+t ) Z=[["License","2008-05-08","2009-03-11","2011-11-22","2013-08-12","2015-11-19"],["GPLv2","58.69%","52.2%","42.5%","33%","23%"],["GPLv3","1.64%","4.15%","6.5%","12%","9%"],["LGPL 2.1","11.39%","9.84%","?","6%","5%"],["LGPL 3.0","? (<0.64%)","0.37%","?","3%","2%"],["GPL family together","71.72% (+ <0.64%)","66.56%","?","54%","39%"]] O.textContent=F(Z) <pre id=O></pre> • Did you mean a=>(? – Neil Jan 17 '16 at 22:56 • (c,i)=>s[i]>(l=c.length)?0:s[i]=l saves you two bytes, I think. – Neil Jan 18 '16 at 0:36 • @Neil 1. yes 2.thanks Jan 18 '16 at 6:47 • @PhiNotPi agreed Feb 15 '16 at 7:50 • Huh, why did that comment hit my inbox? – Neil Feb 15 '16 at 8:56 # CJam, 58 bytes Anyone know trick of golfing in CJam? q~z_{:,:e>)}%_{)'-*'++}%'+\+N+@@.{f{Se]"| "\+}}z'|N+f+1$f+


# Python 2, 190

This solution makes use of list comprehensions and generator expressions. It accepts a list of lists, and returns a string in the required format.

def b(i):
d=[max(map(len,c))for c in zip(*i)]
a='+'+''.join('-'*h+'--+'for h in d)
e=['|'+''.join(' '+f.ljust(h)+' |'for h,f in zip(d,j))for j in i]
return'\n'.join([a,e[0],a]+e[1:]+[a])


The code before the minifier:

def mktable(data):
sizes = [max(map(len, column)) for column in zip(*data)]
divider = '+' + ''.join('-'*size+'--+' for size in sizes)
lines = ['|' + ''.join(
' ' + value.ljust(size) + ' |' for size, value in zip(sizes, row)
)
for row in data]
return '\n'.join([divider, lines[0], divider] + lines[1:] + [divider])

data = [
["GPLv2","58.69%","52.2%","42.5%","33%","23%"],
["GPLv3","1.64%","4.15%","6.5%","12%","9%"],
["LGPL 2.1","11.39%","9.84%","?","6%","5%"],
["LGPL 3.0","? (<0.64%)","0.37%","?","3%","2%"],
["GPL family together","71.72% (+ <0.64%)","66.56%","?","54%","39%"]
]

table = mktable(data)
print table


which outputs:

+---------------------+-------------------+------------+------------+------------+------------+
| License             | 2008-05-08        | 2009-03-11 | 2011-11-22 | 2013-08-12 | 2015-11-19 |
+---------------------+-------------------+------------+------------+------------+------------+
| GPLv2               | 58.69%            | 52.2%      | 42.5%      | 33%        | 23%        |
| GPLv3               | 1.64%             | 4.15%      | 6.5%       | 12%        | 9%         |
| LGPL 2.1            | 11.39%            | 9.84%      | ?          | 6%         | 5%         |
| LGPL 3.0            | ? (<0.64%)        | 0.37%      | ?          | 3%         | 2%         |
| GPL family together | 71.72% (+ <0.64%) | 66.56%     | ?          | 54%        | 39%        |
+---------------------+-------------------+------------+------------+------------+------------+

• I was sad that this almost but did not quite work: from tabulate import*;a=input();print tabulate(a[1:],a[0],'psql',numalign='left') Jan 22 '16 at 15:29
• 185 bytes: Try it online! Dec 17 '18 at 16:16

# MATLAB, 244 239 229 226

a=eval(regexprep(input(''),{'], *?[','[[',']]','"'},{';','{','}',''''}));s=size(a);c=repmat(' | ',s(1),1);b=c;for i=1:s(2)
x=char(a{:,i});b=[b x c];end
h=b(1,:);r=h*0+'-';r(h=='|')='+';b=[r;h;r;b(2:end,:);r];disp(b(:,2:end-1))


Explanation to follow.

Test case:

Input:

'[["License","2008-05-08","2009-03-11","2011-11-22","2013-08-12","2015-11-19"],["GPLv2","58.69%","52.2%","42.5%","33%","23%"],["GPLv3","1.64%","4.15%","6.5%","12%","9%"],["LGPL 2.1","11.39%","9.84%","?","6%","5%"],["LGPL 3.0","? (<0.64%)","0.37%","?","3%","2%"],["GPL family together","71.72% (+ <0.64%)","66.56%","?","54%","39%"]]'


Output:

+---------------------+-------------------+------------+------------+------------+------------+
| License             | 2008-05-08        | 2009-03-11 | 2011-11-22 | 2013-08-12 | 2015-11-19 |
+---------------------+-------------------+------------+------------+------------+------------+
| GPLv2               | 58.69%            | 52.2%      | 42.5%      | 33%        | 23%        |
| GPLv3               | 1.64%             | 4.15%      | 6.5%       | 12%        | 9%         |
| LGPL 2.1            | 11.39%            | 9.84%      | ?          | 6%         | 5%         |
| LGPL 3.0            | ? (<0.64%)        | 0.37%      | ?          | 3%         | 2%         |
| GPL family together | 71.72% (+ <0.64%) | 66.56%     | ?          | 54%        | 39%        |
+---------------------+-------------------+------------+------------+------------+------------+


# Ruby, 129126127 126 characters

->a{t=?|
a.transpose.map{|c|t+=" %-#{c.map(&:size).max}s |"}
[d=(t%a[0].map{p}).tr('| ','+-'),a.map{|r|t%r}.insert(1,d),d]*$/}  Sample run: 2.1.5 :001 > puts ->a{t=?|;a.transpose.map{|c|t+=" %-#{c.map(&:size).max}s |"};[d=(t%a[0].map{p}).tr('| ','+-'),a.map{|r|t%r}.insert(1,d),d]*$/}[[["License","2008-05-08","2009-03-11","2011-11-22","2013-08-12","2015-11-19"],["GPLv2","58.69%","52.2%","42.5%","33%","23%"],["GPLv3","1.64%","4.15%","6.5%","12%","9%"],["LGPL 2.1","11.39%","9.84%","?","6%","5%"],["LGPL 3.0","? (<0.64%)","0.37%","?","3%","2%"],["GPL family together","71.72% (+ <0.64%)","66.56%","?","54%","39%"]]]
+---------------------+-------------------+------------+------------+------------+------------+
| License             | 2008-05-08        | 2009-03-11 | 2011-11-22 | 2013-08-12 | 2015-11-19 |
+---------------------+-------------------+------------+------------+------------+------------+
| GPLv2               | 58.69%            | 52.2%      | 42.5%      | 33%        | 23%        |
| GPLv3               | 1.64%             | 4.15%      | 6.5%       | 12%        | 9%         |
| LGPL 2.1            | 11.39%            | 9.84%      | ?          | 6%         | 5%         |
| LGPL 3.0            | ? (<0.64%)        | 0.37%      | ?          | 3%         | 2%         |
| GPL family together | 71.72% (+ <0.64%) | 66.56%     | ?          | 54%        | 39%        |
+---------------------+-------------------+------------+------------+------------+------------+
`