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","? (&lt;0.64%)","0.37%","?","3%","2%"],["GPL family together","71.72% (+ &lt;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            | ? (&lt;0.64%)        | 0.37%      | ?          | 3%         | 2%         |
| GPL family together | 71.72% (+ &lt;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 &lt; 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('+') + '+';
    if (header) {
        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 code-golf, so the submission with the least amount of bytes wins!
vim, 139 138 134

$x0xqq%ls&lt;cr&gt;&lt;esc&gt;@qq@q:se nosol|%s/,/\t/g|%s/]/\t./|%!column -t -s'&lt;C-v&gt;&lt;Tab&gt;'&lt;cr&gt;qwf";;h&lt;C-v&gt;GI|&lt;esc&gt;@wq@wll&lt;C-v&gt;Gls|&lt;esc&gt;0&lt;C-v&gt;Gs| &lt;esc&gt;:%s/"//g&lt;cr&gt;Yp:s/[^|]/-/g|s/|/+/g&lt;cr&gt;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./&lt;cr&gt; can be replaced with qe$s&lt;Tab&gt;.&lt;esc&gt;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&lt;cr&gt;    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&lt;cr&gt;&lt;esc&gt;    put each element of the big array on its own line
 @qq             recurse
@q               play back the macro until EOF
:%s/,/\t/g&lt;cr&gt;   replace all remaining commas with tabs
:%s/]/\t./&lt;cr&gt;   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'&lt;C-v&gt;&lt;Tab&gt;
 '&lt;cr&gt;
qw               record another macro
 f";;            go forward 3 "s--that is, to the next "column"
 h               go back to the middle of the column
 &lt;C-v&gt;GI|&lt;esc&gt;   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
&lt;C-v&gt;Gl          select the dots
s|&lt;esc&gt;          replace with a line (top to bottom)
0&lt;C-v&gt;G          select all the opening brackets
s| &lt;esc&gt;         again, (the leftmost) line
:%s/"//g&lt;cr&gt;     kill all the quotes around the data
Yp               duplicate bottom line
:s/[^|]/-/g&lt;cr&gt;  replace everything that's not a line with a dash
:s/|/+/g&lt;cr&gt;     now replace the lines with plus signs
YggpkP           put the separators before and after the first line


Thanks smpl for a byte!