使用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;
}
}
}
}
问题实际上是你的数字是字符串。所以'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;
}
}
}
您需要将表格单元格的值转换为数字,如果它是一个数字,并把它作为一个字符串,如果它是一个名字。这样做会使这两种情况的比较工作。下面是一些更新的代码:
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);
此代码没有工作,我认为是因为你的改变。我认为它应该是在上面和外面'if(dir ==“asc”){'如果你在这个页面上查看其他答案,那么这个代码的作用和你的类似。如果您阅读了我的最新回复,我有一个新问题......在某些栏目中,我使用' - '作为空白以表示相当于'N/A',这显然不是数字。任何包含该符号的列都不能正确分类。有没有办法解决?或者一种方法来转换该符号,使其基本上等于0(不必写入0)? – bevstar7
@ bevstar7你是对的,它是在错误的地方!我还添加了一个测试来处理列中'-'的情况。如果为了排序目的而遇到'-',则返回'0'。此代码正在为我工作并处理'-'情况。 – Hendeca
我设法使用其他代码来解决我的问题(他们也解决了' - '问题),但只是尝试了你的,它也可行!谢谢您的帮助。 – bevstar7
嗨,这个伟大的作品整理我的数字列,但它阻止我能够按字母顺序排序我的第一列。现在只有数字可以被排序。 – bevstar7
正如stevelacerda7所解释的那样,您可以检查parseInt是否导致NaN,并在此情况下执行正常的字符串比较。 – teldri
我该怎么做? – bevstar7