根据第一个表中行的下降总和创建另一个表

时间:2015-04-06 13:01:14

标签: javascript html css arrays sorting

这里我有一个初始表,我使用rcm.create()方法创建。然后我必须创建另一个行,将根据第一个表的行的降序求和排序行。这意味着行有更高的和将放在第二个表的第一个。为了创建第二个表我有rcm.generateTab2()方法。其工作如下;

1.call rcm.create()方法创建第二个表。

2.从第一个表创建每行的总和,并将其推入包含对象数组的rank数组中。

3.rank数组根据降序值

排序

现在rank数组包含三个元素的对象。

每行的第一个td值。

行数

和将用于在第二个表的tbody中插入行的完整行

4.删除第二个表中的.tbody元素。

5.然后创建一个新的并尝试将表1的已排序行插入表2。

但我得到的是表2在浏览器中被推到表1之上并且没有插入任何行。

完整代码:jsfiddle

enter image description here

主要问题是在rcm.generateTab2方法内部。所以我在这里单独发布。

rcm.generateTab2方法:

    generateTab2:function(){
                var power=0;
                this.create(machine,process); //create the second table

                var tbody=document.getElementsByTagName('tbody')[0];
                var trow=tbody.getElementsByTagName('tr');

                for(i=0;i<trow.length;i++){  //get summation
                     var td=trow[i].getElementsByTagName('td');
                     var sum=0;

                     for(j=td.length-1;j>0;j--){

                        if(td[j].innerHTML==''){
                            sum+=0*Math.pow(2,power);
                        }else{
                             sum+=parseInt(td[j].innerHTML)*Math.pow(2,power);

                        }

                         power++;
                     }
                     var first=parseInt(td[0].innerHTML);
                     rank.push({rowNo:first,sum:sum,row:trow[i]}); //pushed to rank array

                     power=0;
                }
                rank.sort(function (a,b){ //rank array is sorted
                    if(a.sum>b.sum){
                         return -1;
                    }else if(a.sum<b.sum){
                         return 1;
                    }else{
                        return 0;
                    }
                });
                console.log(rank);

                var parent=document.getElementsByTagName('table')[1];
                parent.removeChild(parent.childNodes[1]);//delete existing tbody from second table


                var newTbody=document.createElement('tbody'); //create a new tbody
                parent.appendChild(newTbody); //append it to second table


             for(i=0;i<rank.length;i++){

                    newTbody.appendChild(rank[i].row);  //insert rows to tbody of second table
            }




    }

1 个答案:

答案 0 :(得分:1)

不确定我是否正确理解排名数学。

请查看下面的演示,并点击此处jsfiddle

我已经重新编码了你的js,因为我认为这更容易。 (但如果你不喜欢使用jQuery,我可以查看你的代码并检查我是否能找到问题。)

我正在使用这些js libs:

  • 用于DOM操作的jQuery
  • 使用_.range创建数组的下划线(也可以使用for循环完成,因此不需要Underscore)
  • Tinysort jQuery plugin用于对表进行排序

对于排序,我已经将排序等级(行的总和)作为数据属性添加到每一行,因此tinysort可以使用它来对表进行排序。

SO处的CSS与表头中的jsFiddle(非居中文本)略有不同。不知道为什么。

表单输入中的默认值(3&amp; 2)只是为了便于调试。只需稍后从输入中删除value属性。


2015年4月7日更新

我发现您的代码存在问题。问题是您已将对table1的引用存储在排名对象中。对象中的tr元素。 因此,您已覆盖table1,因为该引用。

您可以使用rank[i].row.cloneNode(true)来克隆行的内容来解决此问题。然后,您可以将其附加到新表中,而不会出现问题。

请参阅更新的小提琴here

&#13;
&#13;
var ROC = {
    init: function (element) {
        this.$el = $(element);
        this.$table1wrap = $('<div/>').attr('id', 'table1wrapper');
        this.$table2wrap = $('<div/>').attr('id', 'table2wrapper');
        this.$el.append([this.$table1wrap, this.$table2wrap]);
    },
    create: function (machine, process) {
        var self = this,
            $tableHeading = $('<tr/>'),
            $table = $('<table/>').attr('id', 'mainTable');

        this.$table1wrap.html($table.append($('<thead/>').html($tableHeading)));

        this.processes = this.createCols(process);
        this.machines = this.createRows(machine);
        //var addRow = function() {
        //    this.$el.append($('tr').html(this.processes));
        //this.$el.append($('<tr/>').html($('<td/>').text('test')));
        $(this.machines).each(function (index, row) {
            //console.log(index, $(row));
            var $curRow = $(row);
            //console.log($tableHeading.length);
            $(self.processes).each(function (i, col) {
                if (index == 0) {
                    var letter = String.fromCharCode(97 + i).toUpperCase();
                    if (i == 0) $tableHeading.append($('<th/>').text('~'));
                    $tableHeading.append($('<th/>').text(letter));
                }
                //console.log(i, $(col));
                // self.$el.append(($(row).clone()).html($(col).clone()));
                if (i == 0) $curRow.append($('<td/>')
                    .text(index + 1)
                    .addClass('rowIndex'));
                $curRow.append($(col).attr('contentEditable', 'true'));
            });

            $table.append($curRow.clone());
        });
        //console.log(this.processes, this.machines);
    },
    createCols: function (cols) {
        var rCols = _.range(cols).map(function (num, index) {
            return $('<td/>').text(0);
        }); // [td, td, ...];
        return rCols;
    },
    createRows: function (rows) {
        var rRows = _.range(rows).map(function (num, index) {
            return $('<tr/>');
        }); // [tr, tr, ...];
        return rRows;
    },
    copy: function (sel) {
        //console.log($(sel));
        var $newTable = $(sel).clone().attr('id', 'copy');
        var $sortedBody = $($newTable)
            .find('tbody')
            .html(this.calcRank($newTable));
        //console.log($sortedBody, this.calcRank($newTable));

        //console.log('sorted', $sortedTable);
        $(this.$table2wrap).html($($newTable, 'tbody').append($sortedBody));
    },
    calcRank: function (newTable) {
        var sum, $col;
        newTable.find('tr').each(function (index, item) {
            //console.log(index, $(item).children());
            $col = $(item).children();
            sum = 0;
            if (index > 0) { // skip heading
                $col.each(function (i, cell) {
                    if (i > 0) sum += parseInt($(cell).text()); // skip first col 
                });
                $(item).attr('data-rank', sum);
            }
            //console.log(index, sum, $(item));
            //$(item).attr('data-rank', sum);
        });
        //console.log($(newTable));

        return tinysort($(newTable).find('tbody>tr'), {
            attr: 'data-rank',
            order: 'desc'
        });
    },
    reset: function () {
        this.$table1wrap.empty();
        this.$table2wrap.empty();
    }
};

ROC.init('#out');

$('#btnCreate').click(function () {
    var proc = $('#process').val(),
        machine = $('#machine').val();

    ROC.create(machine, proc);
});

$('#btnCreate2').click(function () {
    ROC.copy('#mainTable');
});

$('#btnRst').click(function () {
    ROC.reset();
});
&#13;
body {
    padding: 1em;
}
input[type='number'] {
    background:lightblue;
    color:crimson;
    margin-left:20px;
}
table {
    border-collapse: initial !important;
    border-spacing: 10px !important;
}
th {
    background:black;
    color:white;
    width:40px;
    height:40px;
    border:1px solid white;
    text-align:center;
    box-shadow:0px 0px 7px black;
}
td {
    box-shadow:0px 0px 7px black;
    background:white;
    width:40px;
    height:40px;
    border:1px solid black;
    text-align:center;
}
td.rowIndex {
    background: black;
    color: white;
}
&#13;
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tinysort/2.1.1/tinysort.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>Rank Order Clustering</h1>

<fieldset>
    <legend style='font-size:30px;background:lightblue;'>insert items</legend>
    <label for='process'>process :</label>
    <input type='number' id='process' placeholder='processes' value="3" />
    <br/>
    <label for='machine'>machines :</label>
    <input type='number' id='machine' placeholder='machines' value="2" />
    <br/>
    <input type='button' value='create table' id='btnCreate' />
    <input type='button' value=' reset' id='btnRst' />
    <input type='button' value='generate table2' id='btnCreate2' />
</fieldset>
<div id="out"></div>
&#13;
&#13;
&#13;