【问题标题】:create another table according to the descending summation of rows from the first table根据第一个表中行的降序求和创建另一个表
【发布时间】:2015-04-06 13:01:14
【问题描述】:

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

1.调用rcm.create()方法创建第二张表。

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

3.rank数组按降序排列

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

每行的第一个 td 值。

总行数

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

4.tbody 元素从第二个表被删除。

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

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

完整代码:jsfiddle

主要问题在 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
            }
                                
             
             
    
    }

【问题讨论】:

    标签: javascript html css arrays sorting


    【解决方案1】:

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

    请看下面的演示,这里是jsfiddle

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

    我正在使用这些 js 库:

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

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

    此处的 CSS 与表格标题中的 jsFiddle(非居中文本)略有不同。不知道为什么。

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


    更新 07.04.2015

    我发现您的代码存在问题。问题是您已经在 rank 对象中存储了对 table1 的引用。对象中的tr 元素。 因此,由于该引用,您已经覆盖了 table1

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

    查看更新的小提琴here

    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();
    });
    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;
    }
    <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>

    【讨论】:

    • 您的代码有效,没关系。但是您没有指出为什么其中一个 tbody 正在消失,我也没有要求 jquery :(
    • 对不起,我的答案的第一部分没有回答你的问题,但你的代码一开始很难理解。但现在我发现了问题,请参阅我的答案中的更新。
    • 我不知道为什么,我的代码总是乱七八糟。反正我也发现了问题。我将每个表行推入一个数组并将它们附加到一个新表中。这导致了所有'tr' 元素从一个表转移到另一个表。这就是为什么一个表的 tbody 元素有 ho 'tr' 元素。然后我也找到了解决方案。我从一个表中克隆了每个 'tr' 元素并附加克隆的元素到另一个。这对我有用。谢谢你的帮助:)
    猜你喜欢
    • 1970-01-01
    • 2017-02-04
    • 2021-03-29
    • 2021-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-20
    相关资源
    最近更新 更多