Функция >drawRow
сперва превращает объекты ячеек строки в блоки, которые являются массивами строк, представляющими содержимое ячеек, разделённые линиями. Одна ячейка, содержащая число 3776, может быть представлена массивом из одного элемента >["3776"]
, а подчёркнутая ячейка может занять две строки и выглядеть как массив >["name", "----"]
.
Блоки для строки, у которых одинаковая высота, должны выводиться рядом друг с другом. Второй вызов >map
в >drawRow
строит этот результат построчно, начиная с ячеек самого левого блока, и для каждой из них дополняя строку до полной ширины таблицы. Полученные строки затем соединяются через символ новой строки, создавая целый ряд, который и возвращает >drawRow
.
Функция >drawLine
выцепляет строки, которые должны располагаться рядом друг с другом, из массива блоков и соединяет их через пробел, чтобы создать промежуток в один символ между столбцами таблицы.
Давайте напишем конструктор для ячеек, содержащих текст, который предоставляет интерфейс для ячеек. Он разбивает строчку в массив строк при помощи метода >split
, который режет строчку каждый раз, когда в ней встречается его аргумент, и возвращает массив полученных кусочков. Метод >minWidth
находит максимальную ширину строки в массиве.
>function repeat(string, times) {
> var result = "";
> for (var i = 0; i < times; i++)
> result += string;
> return result;
>}
>function TextCell(text) {
> this.text = text.split("\n");
>}
>TextCell.prototype.minWidth = function() {
> return this.text.reduce(function(width, line) {
> return Math.max(width, line.length);
> }, 0);
>};
>TextCell.prototype.minHeight = function() {
> return this.text.length;
>};
>TextCell.prototype.draw = function(width, height) {
> var result = [];
> for (var i = 0; i < height; i++) {
> var line = this.text[i] || "";
> result.push(line + repeat(" ", width - line.length));
> }
> return result;
>};
В коде используется вспомогательная функция >repeat
, которая возвращает переданную первым аргументом строку, повторённую переданное вторым аргументом количество раз. Метод >draw
использует её для создания отступов в ячейках, чтобы они все были необходимой длины.
Давайте нарисуем для опыта шахматную доску 5×5.
>var rows = [];
>for (var i = 0; i < 5; i++) {
> var row = [];
> for (var j = 0; j < 5; j++) {
> if ((j + i) % 2 == 0)
> row.push(new TextCell("##"));
> else
> row.push(new TextCell(" "));
> }
> rows.push(row);
>}
>console.log(drawTable(rows));
>// → ## ## ##
>// ## ##
>// ## ## ##
>// ## ##
>// ## ## ##
Работает! Но так как у всех ячеек один размер, код форматирования таблицы не делает ничего интересного.