JS 多态 继承

程序解决的问题为:给一个json,以表格的形式输出它。

表格的格式是左对齐或者右对齐,表格头部有下划线标识,每个表格块的大小取决于该行最大高,和该列最大宽。

以对象的思维方式去解决。

需要一个表格块对象,该对象保存该块的宽和高,字符内容(因为该块有可能是多行字符,随意用字符数组保存),以及讲该快画成指定格式的draw函数。

然后是一个表头对象,该对象使用表格对象的方法。

dataTable()函数将数据处理成二维数组。

drawTable将该二维数组格式化为字符串。

用到很多map,reduce。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    var MOUNTAINS = [
        {name: ["aaaaa \nkkkk\n\n\nnn\n dsadasd\ndjsioajdoiwjioajwdoioj"], height: "aaa", country: "aaaaa"},
        {name: "aaaaa", height: 8848, country: "Nepal"},
        {name: "Mount Fuji", height: 3776, country: "Japan"},
        {name: "Mont Blanc", height: 4808, country: "Italy/France\ndfjsioajdiojaijdioajoidjoijasoijdwoijiod"},
        {name: "Vaalserberg", height: 323, country: "Netherlands"},
        {name: "Denali", height: 6168, country: "United States"},
        {name: "Popocatepetl", height: 5465, country: "Mexico"}
    ];
    function rowHeights(rows){//计算每行最高的行高
        return rows.map(function(row){
            return row.reduce(function(max,cell){
                return Math.max(max,cell.minHeight());
            },0)
        })
    }
    function colWidths(rows){//计算每列最宽的宽度
        return rows[0].map(function(_,i){
            return rows.reduce(function(max,row){
                return Math.max(max,row[i].minWidth());
            },0)//这里必须为0 ,如果是默认,reduce会在第二个值开始进行合并操作, 这里的默认初始值为row为数组
        })
    }

    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]||"";
            console.log(line);
            result.push(line+repeat(" ",width-line.length));
        }

        return result;
    }
    function UnderlineCell(inner){
        this.inner = inner;
    }
    UnderlineCell.prototype.minWidth = function() {
        return this.inner.minWidth();
    };
    UnderlineCell.prototype.minHeight = function() {
        return this.inner.minHeight() + 1;
    };
    UnderlineCell.prototype.draw = function(width, height) {
        return this.inner.draw(width, height - 1)
            .concat([repeat("-", width)]);
    };

    function dataTable(data){
        var keys=Object.keys(data[0]);
        var header=keys.map(function(name){
            return new UnderlineCell(new TextCell(name));
        });
        var body=data.map(function(row){
            return keys.map(function(name){
                var value=row[name];
                if(typeof name == "number")
                    return new RTextCell(String(value));
                else
                    return new TextCell(String(value));
            })
        });

        return [header].concat(body);
    }

    function drawTable(rows){
        var heights = rowHeights(rows);
        var widths=colWidths(rows);

        function drawLine(blocks,lineNo){
            return blocks.map(function(block){
                return block[lineNo];
            }).join(" ");
        }
        function drawRow(row,rowNum){
            var blocks=row.map(function(cell,colNum){
                return cell.draw(widths[colNum],heights[rowNum])
            });

            return blocks[0].map(function(_,lineNo){
                return drawLine(blocks,lineNo);
            }).join("\n");
        }

        return rows.map(drawRow).join("\n");
    }
    //继承
    function RTextCell(text){
        TextCell.call(this,text);//这里call调用TextCell函数,这里为分离组合继承
    }
    RTextCell.prototype=Object.create(TextCell.prototype);
    RTextCell.prototype.draw=function(width,height){
        var result=[];
        for(var i=0;i<height;i++){
            var line=this.text[i]||"";
            result.push(repeat(" ",width-line.length)+line);
        }
        return result;
    }
    console.log(Object.getPrototypeOf(TextCell) ==Object.getPrototypeOf(UnderlineCell));

    console.log(drawTable(dataTable(MOUNTAINS)));
</script>
</body>
</html>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值