繁体   English   中英

使用Java进行数字和字母排序表

[英]Sort table both numerically and alphabetically using Javascript

我有一个表,该表通过单击标题来工作,然后每次单击标题时,该表都会按升序和降序对列进行排序。 它按字母顺序对所有内容进行排序,但我需要它也能够进行数字排序。

在数字超出同一列中的单个数字之前,它似乎一直有效。

这是HTML代码:(忽略NFL内容,仅是测试该表的数据)

<div id="supAll">
            <table border="1" class="supTable">
                <tr> 
                    <th onclick="sortTable('supTable', 0)">Team</th>
                    <th onclick="sortTable('supTable', 1)">SB Wins</th>
                    <th onclick="sortTable('supTable', 2)">SB Losses</th>
                    <th onclick="sortTable('supTable', 3)">Last Won</th>
                </tr>
                <tr class="nfc nfcWest">
                    <td>Arizona Cardinals</td>
                    <td>0</td>
                    <td>1</td>
                    <td>-</td>
                </tr>
                <tr class="nfc nfcSouth">
                    <td>Atlanta Falcons</td>
                    <td>10</td>
                    <td>2</td>
                    <td>-</td>
                </tr>
                <tr class="afc afcNorth">
                    <td>Baltimore Ravens</td>
                    <td>2</td>
                    <td>0</td>
                    <td>2012</td>
                </tr>
                <tr class="afc afcEast">
                    <td>Buffalo Bills</td>
                    <td>11</td>
                    <td>4</td>
                    <td>-</td>
                </tr>
                <tr class="nfc nfcSouth">
                    <td>Carolina Panthers</td>
                    <td>22</td>
                    <td>2</td>
                    <td>-</td>
                </tr>
                <tr class="nfc nfcNorth">
                    <td>Chicago Bears</td>
                    <td>1</td>
                    <td>1</td>
                    <td>1985</td>
                </tr>
                <tr class="afc afcNorth">
                    <td>Cincinnati Bengals</td>
                    <td>0</td>
                    <td>2</td>
                    <td>-</td>
                </tr>
                <tr class="afc afcNorth">
                    <td>Cleveland Browns</td>
                    <td>0</td>
                    <td>0</td>
                    <td>-</td>
                </tr>
                <tr class="nfc nfcEast">
                    <td>Dallas Cowboys</td>
                    <td>5</td>
                    <td>3</td>
                    <td>1995</td>
                </tr>
                <tr class="afc afcWest">
                    <td>Denver Broncos</td>
                    <td>3</td>
                    <td>5</td>
                    <td>2015</td>
                </tr>
                <tr class="nfc nfcNorth">
                    <td>Detroit Lions</td>
                    <td>0</td>
                    <td>0</td>
                    <td>-</td>
                </tr>
                <tr class="nfc nfcNorth">
                    <td>Green Bay Packers*</td>
                    <td>4</td>
                    <td>1</td>
                    <td>2010</td>
                </tr>
                <tr class="afc afcSouth">
                    <td>Houston Texans</td>
                    <td>0</td>
                    <td>0</td>
                    <td>-</td>
                </tr>
                <tr class="afc afcSouth">
                    <td>Indianapolis Colts</td>
                    <td>2</td>
                    <td>2</td>
                    <td>2006</td>
                </tr>
                <tr class="afc afcSouth">
                    <td>Jacksonville Jaguars</td>
                    <td>0</td>
                    <td>0</td>
                    <td>-</td>
                </tr>
                <tr class="afc afcWest">
                    <td>Kansas Chiefs*</td>
                    <td>1</td>
                    <td>1</td>
                    <td>1969</td>
                </tr>
                <tr class="afc afcWest">
                    <td>Los Angeles Chargers</td>
                    <td>0</td>
                    <td>1</td>
                    <td>-</td>
                </tr>
                <tr class="nfc nfcWest">
                    <td>Los Angeles Rams</td>
                    <td>1</td>
                    <td>2</td>
                    <td>1999</td>
                </tr>
                <tr class="afc afcEast">
                    <td>Miami Dolphins</td>
                    <td>2</td>
                    <td>3</td>
                    <td>1973</td>
                </tr>
                <tr class="nfc nfcNorth">
                    <td>Minnesota Vikings</td>
                    <td>0</td>
                    <td>4</td>
                    <td>-</td>
                </tr>
                <tr class="afc afcEast">
                    <td>New England Patriots</td>
                    <td>5</td>
                    <td>4</td>
                    <td>2016</td>
                </tr>
                <tr class="nfc nfcSouth">
                    <td>New Orleans Saints</td>
                    <td>1</td>
                    <td>1</td>
                    <td>2009</td>
                </tr>
                <tr class="nfc nfcEast">
                    <td>New York Giants</td>
                    <td>4</td>
                    <td>1</td>
                    <td>2011</td>
                </tr>
                <tr class="afc afcEast">
                    <td>New York Jets*</td>
                    <td>1</td>
                    <td>0</td>
                    <td>1968</td>
                </tr>
                <tr class="afc afcWest">
                    <td>Oakland Raiders</td>
                    <td>3</td>
                    <td>2</td>
                    <td>1983</td>
                </tr>
                <tr class="nfc nfcEast">
                    <td>Philadelphia Eagles</td>
                    <td>0</td>
                    <td>2</td>
                    <td>-</td>
                </tr>
                <tr class="afc afcNorth">
                    <td>Pittsburgh Steelers</td>
                    <td>6</td>
                    <td>2</td>
                    <td>2008</td>
                </tr>
                <tr class="nfc nfcWest">
                    <td>San Francisco 49ers</td>
                    <td>5</td>
                    <td>5</td>
                    <td>1994</td>
                </tr>
                <tr class="nfc nfcWest">
                    <td>Seattle Seahawks</td>
                    <td>1</td>
                    <td>2</td>
                    <td>2013</td>
                </tr>
                <tr class="nfc nfcSouth">
                    <td>Tampa Bay Buccaneers</td>
                    <td>1</td>
                    <td>0</td>
                    <td>2002</td>
                </tr>
                <tr class="afc afcSouth">
                    <td>Tennessee Titans</td>
                    <td>0</td>
                    <td>1</td>
                    <td>-</td>
                </tr>
                <tr class="nfc nfcEast">
                    <td>Washington Redskins</td>
                    <td>3</td>
                    <td>2</td>
                    <td>1991</td>
                </tr>
            </table>
        </div>      
    </div>

下面是Javascript代码:

function sortTable(tableClass, n) {
var table, rows, switching, i, x, y, shouldSwitch, dir, switchcount = 0;

table = document.getElementsByClassName(tableClass)[0];
switching = true;
dir = "asc";
while (switching) {
    switching = false;
    rows = table.getElementsByTagName("TR");
    for (i = 1; i < (rows.length - 1); i++) {
        shouldSwitch = false;
        x = rows[i].getElementsByTagName("TD")[n];
        y = rows[i + 1].getElementsByTagName("TD")[n];
        if (dir == "asc") {
            if (x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()) {
                shouldSwitch= true;
                break;
            }
        } else if (dir == "desc") {
            if (x.innerHTML.toLowerCase() < y.innerHTML.toLowerCase()) {
                shouldSwitch= true;
                break;
            }
        }
    }
    if (shouldSwitch) {
        rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
        switching = true;
        switchcount ++;      
    } else {
        if (switchcount == 0 && dir == "asc") {
            dir = "desc";
            switching = true;
        }
    }
}

}

如果运行代码,您会在中间一栏中看到大小不同的数字,但该数字已不再正确排序。

有什么方法可以使用此代码/功能,以便我的表可以按字母和数字进行排序(当它超过单个数字时)? 如果不能,请帮助我解决此问题。

编辑-这已解决! 如果您同时查看Hendeca和Teldri的以下代码,则将看到已解决的代码。 它们的两个版本都可以工作。

您应该在比较之前将数值解析为整数或浮点型

所以

if (x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()) {

更改为

if (parseInt(x.innerHTML) > parseInt(y.innerHTML)) {

字符串比较(如果没有数字)

var cmpX=isNaN(parseInt(x.innerHTML))?x.innerHTML.toLowerCase():parseInt(x.innerHTML);

var cmpY=isNaN(parseInt(y.innerHTML))?y.innerHTML.toLowerCase():parseInt(y.innerHTML);

if (parseInt(cmpX) > parseInt(cmpY)) {

将您的功能更改为此:

function sortTable(tableClass, n) {
var table, rows, switching, i, x, y, shouldSwitch, dir, switchcount = 0;

table = document.getElementsByClassName(tableClass)[0];
switching = true;
dir = "asc";
while (switching) {
    switching = false;
    rows = table.getElementsByTagName("TR");
    for (i = 1; i < (rows.length - 1); i++) {
        shouldSwitch = false;
        x = rows[i].getElementsByTagName("TD")[n];
        y = rows[i + 1].getElementsByTagName("TD")[n];
                var cmpX=isNaN(parseInt(x.innerHTML))?x.innerHTML.toLowerCase():parseInt(x.innerHTML);
                var cmpY=isNaN(parseInt(y.innerHTML))?y.innerHTML.toLowerCase():parseInt(y.innerHTML);
cmpX=(cmpX=='-')?0:cmpX;
cmpY=(cmpY=='-')?0:cmpY;
        if (dir == "asc") {
            if (cmpX > cmpY) {
                shouldSwitch= true;
                break;
            }
        } else if (dir == "desc") {
            if (cmpX < cmpY) {
                shouldSwitch= true;
                break;
            }
        }
    }
    if (shouldSwitch) {
        rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
        switching = true;
        switchcount ++;      
    } else {
        if (switchcount == 0 && dir == "asc") {
            dir = "desc";
            switching = true;
        }
    }
}
}

如果是数字,则需要将表单元格值转换为数字,如果是名称,则需要将其保留为字符串。 这样做将使两种情况下的比较都可以进行。 这是一些更新的代码:

function sortTable(tableClass, n) {
  var table, rows, switching, i, x, y, shouldSwitch, dir, switchcount = 0;

  table = document.getElementsByClassName(tableClass)[0];
  switching = true;
  dir = "asc";
  while (switching) {
      switching = false;
      rows = table.getElementsByTagName("TR");
      for (i = 1; i < (rows.length - 1); i++) {
          shouldSwitch = false;
          x = rows[i].getElementsByTagName("TD")[n];
          y = rows[i + 1].getElementsByTagName("TD")[n];
          var xContent = (isNaN(x.innerHTML)) 
              ? (x.innerHTML.toLowerCase() === '-')
                    ? 0 : x.innerHTML.toLowerCase()
              : parseFloat(x.innerHTML);
          var yContent = (isNaN(y.innerHTML)) 
              ? (y.innerHTML.toLowerCase() === '-')
                    ? 0 : y.innerHTML.toLowerCase()
              : parseFloat(y.innerHTML);
          if (dir == "asc") {
              if (xContent > yContent) {
                  shouldSwitch= true;
                  break;
              }
          } else if (dir == "desc") {
              if (xContent < yContent) {
                  shouldSwitch= true;
                  break;
              }
          }
      }
      if (shouldSwitch) {
          rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
          switching = true;
          switchcount ++;      
      } else {
          if (switchcount == 0 && dir == "asc") {
              dir = "desc";
              switching = true;
          }
      }
   }
}

通过测试字符串是否为数字,可以确定是否转换该值。 这是相关的更改:

var xContent = (isNaN(x.innerHTML)) ? x.innerHTML.toLowerCase() : parseFloat(x.innerHTML);
var yContent = (isNaN(y.innerHTML)) ? y.innerHTML.toLowerCase() : parseFloat(y.innerHTML);

编辑:添加了一些代码来处理-字符的情况,并将转换后的数字字符串转换为浮点数,而不是整数来处理十进制数字。 新的检查是:

var xContent = (isNaN(x.innerHTML)) 
        ? (x.innerHTML.toLowerCase() === '-')
            ? 0 : x.innerHTML.toLowerCase()
        : parseFloat(x.innerHTML);
var yContent = (isNaN(y.innerHTML)) 
        ? (y.innerHTML.toLowerCase() === '-')
            ? 0 : y.innerHTML.toLowerCase()
        : parseFloat(y.innerHTML);

问题实际上是您的数字是字符串。 因此,“ 14”小于“ 4”。 您可以先尝试转换为数字,如果是isNaN,则可以将其作为字符串进行测试,否则可以作为数字进行测试。

_sortTable: function(n, context) {
    var table, rows, switching, i, x, y, shouldSwitch, dir, switchcount = 0;
    table = document.getElementById(context.options.id);
    switching = true;

    //Set the sorting direction to ascending:
    dir = "asc"; 
    /*Make a loop that will continue until
    no switching has been done:*/
    while (switching) {
        //start by saying: no switching is done:
        switching = false;
        rows = table.getElementsByClassName("row");
        /*Loop through all table rows (except the
        first, which contains table headers):*/
        for (i = 0; i < (rows.length - 1); i++) {
            //start by saying there should be no switching:
            shouldSwitch = false;
            /*Get the two elements you want to compare,
            one from current row and one from the next:*/
            x = rows[i].getElementsByClassName("cell")[n];
            y = rows[i + 1].getElementsByClassName("cell")[n];
            /*check if the two rows should switch place,
            based on the direction, asc or desc:*/
            x = Number(x.innerHTML.toLowerCase()) ? Number(x.innerHTML.toLowerCase()) : x.innerHTML.toLowerCase();
            y = Number(y.innerHTML.toLowerCase()) ? Number(y.innerHTML.toLowerCase()) : y.innerHTML.toLowerCase();

            if (dir == "asc") {
                if (x > y) {
                    //if so, mark as a switch and break the loop:
                    shouldSwitch= true;
                    break;
                }
            } else if (dir == "desc") {
                if (x < y) {
                    //if so, mark as a switch and break the loop:
                    shouldSwitch= true;
                    break;
                }
            }
        }
        if (shouldSwitch) {
            /*If a switch has been marked, make the switch
            and mark that a switch has been done:*/
            rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
            switching = true;
            //Each time a switch is done, increase this count by 1:
            switchcount ++; 
        } else {
            /*If no switching has been done AND the direction is "asc",
            set the direction to "desc" and run the while loop again.*/
            if (switchcount == 0 && dir == "asc") {
            dir = "desc";
            switching = true;
            }
        }
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM