2016年9月9日金曜日

開発環境

Eloquent JavaScript(Marijn Haverbeke 著、No Starch Press)のPart 1(Language)、Chapter 6(The Secret Life of Objects)、Exercises(Another Cell)を取り組んでみる。

Exercises(Another Cell)

コード(Emacs)

'use strict';
var repeat,
    TextCell,
    StretchCell,
    rows = [],
    row = [],
    i,
    j,
    max = 5,
    rowHeights,
    colWidths,
    drawTable;

rowHeights = function (rows) {
    return rows.map(function (row) {
        return row.reduce(function (max, cell) {
            return Math.max(max, cell.minHeight());
        }, 0);
    });
};
colWidths = function (rows) {
    return rows[0].map(function (_, i) {
        return rows.reduce(function (max, row) {
            return Math.max(max, row[i].minWidth());
        }, 0);
    });
};
drawTable = function (rows) {
    var heights = rowHeights(rows),
        widths = colWidths(rows),
        drawLine,
        drawRow;

    drawLine = function (blocks, line_no) {
        return blocks.map(function (block) {
            return block[line_no];
        }).join(' ');
    };
    drawRow = function (row, row_num) {
        var blocks = row.map(function (cell, col_num) {
            return cell.draw(widths[col_num], heights[row_num]);
        });
        return blocks[0].map(function (_, line_no) {
            return drawLine(blocks, line_no);
        }).join('\n');
    };
    return rows.map(drawRow).join('\n');
};

repeat = function (string, times) {
    var result = '',
        i;

    for (i = 0; i < times; i += 1) {
        result += string;
    }
    return result;
};
TextCell = function (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 = [],
        i,
        line;
    
    for (i = 0; i < height; i += 1) {
        line = this.text[i] || '';
        result.push(line + repeat(' ', width - line.length));
    }
    return result;
};

StretchCell = function (inner, width, height) {
    this.inner = inner;
    this.width = width;
    this.height = height;
};
StretchCell.prototype.minWidth = function () {
    return Math.max(this.inner.minWidth(), this.width);
};
StretchCell.prototype.minHeight = function () {
    return Math.max(this.inner.minHeight(), this.height);
};
StretchCell.prototype.draw = function (width, height) {
    var result = [],
        line;

    for (i = 0; i < height; i += 1) {
        line = this.inner.text[i] || '';
        result.push(line + repeat(' ', width - line.length));
    }
    return result;
};
for (i = 0; i < max; i += 1) {
    row = [];
    for (j = 0; j < max; j += 1) {
        if ((j + i) % 2 === 0) {
            row.push(new StretchCell(new TextCell('##'), 5, 6));
        } else {
            row.push(new StretchCell(new TextCell(' '), 5, 6));
        }
    }
    rows.push(row);
}
console.log(drawTable(rows));

入出力結果(Terminal, Node.js)

$ node sample2.js
##          ##          ##   
                             
                             
                             
                             
                             
      ##          ##         
                             
                             
                             
                             
                             
##          ##          ##   
                             
                             
                             
                             
                             
      ##          ##         
                             
                             
                             
                             
                             
##          ##          ##   
                             
                             
                             
                             
                             
$ 

0 コメント:

コメントを投稿