使用Javascript按数字和字母顺序排序表格

问题描述:

我有一个表格,它通过点击一个标题来工作,然后每次单击标题时按照升序和降序对列进行排序。它按字母顺序对所有内容进行排序,但我需要它也能够按数字排序。使用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,您将看到解决的代码。他们的两个版本都有效。

你应该分析的数值为整数或浮点数comparsion之前

所以

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

变化

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

串comparsion如果没有数

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; 
     } 
    } 
} 
} 
+0

嗨,这个伟大的作品整理我的数字列,但它阻止我能够按字母顺序排序我的第一列。现在只有数字可以被排序。 – bevstar7

+0

正如stevelacerda7所解释的那样,您可以检查parseInt是否导致NaN,并在此情况下执行正常的字符串比较。 – teldri

+0

我该怎么做? – bevstar7

问题实际上是你的数字是字符串。所以'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; 
      } 
     } 
    } 
+0

我该怎么做? – bevstar7

+0

本页另外两个答案设法解决了我的问题。感谢您的帮助。 – bevstar7

您需要将表格单元格的值转换为数字,如果它是一个数字,并把它作为一个字符串,如果它是一个名字。这样做会使这两种情况的比较工作。下面是一些更新的代码:

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); 
+1

此代码没有工作,我认为是因为你的改变。我认为它应该是在上面和外面'if(dir ==“asc”){'如果你在这个页面上查看其他答案,那么这个代码的作用和你的类似。如果您阅读了我的最新回复,我有一个新问题......在某些栏目中,我使用' - '作为空白以表示相当于'N/A',这显然不是数字。任何包含该符号的列都不能正确分类。有没有办法解决?或者一种方法来转换该符号,使其基本上等于0(不必写入0)? – bevstar7

+0

@ bevstar7你是对的,它是在错误的地方!我还添加了一个测试来处理列中'-'的情况。如果为了排序目的而遇到'-',则返回'0'。此代码正在为我工​​作并处理'-'情况。 – Hendeca

+0

我设法使用其他代码来解决我的问题(他们也解决了' - '问题),但只是尝试了你的,它也可行!谢谢您的帮助。 – bevstar7