我有下表正在尝试排序升序&使用以下JavaScript代码降序onclick
:
function sortTable(n) {
var table, rows, switching, i, x, y, shouldSwitch, dir, switchcount = 0;
table = document.getElementById("myTable");
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.getElementsByTagName("TR");
/*Loop through all table rows (except the
first, which contains table headers):*/
for (i = 1; 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].getElementsByTagName("TD")[n];
y = rows[i + 1].getElementsByTagName("TD")[n];
/*check if the two rows should switch place,
based on the direction, asc or desc:*/
if (dir == "asc") {
if (x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()) {
//if so, mark as a switch and break the loop:
shouldSwitch = true;
break;
}
} else if (dir == "desc") {
if (x.innerHTML.toLowerCase() < y.innerHTML.toLowerCase()) {
//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;
}
}
}
}
<div class="table-responsive">
<table class="table table-striped" id="myTable">
<tr>
<th onclick="sortTable(0)">Date <i class='fa fa-caret-down'></i></th>
<th onclick="sortTable(1)">Views <i class='fa fa-caret-down'></i></th>
<th onclick="sortTable(2)">Clicks <i class='fa fa-caret-down'></i></th>
<th onclick="sortTable(3)">CTR <i class='fa fa-caret-down'></i></th>
<th onclick="sortTable(4)">Earned <i class='fa fa-caret-down'></i></th>
<th onclick="sortTable(5)">eCPM <i class='fa fa-caret-down'></i></th>
</tr>
<tr>
<td>2017-11-30</td>
<td>4133</td>
<td>3</td>
<td>0.07%</td>
<td>$0.03</td>
<td>$0.0073</td>
</tr>
<tr>
<td>2017-11-29</td>
<td>8340</td>
<td>5</td>
<td>0.06%</td>
<td>$0.05</td>
<td>$0.006</td>
</tr>
<tr>
<td>2017-11-28</td>
<td>7410</td>
<td>5</td>
<td>0.07%</td>
<td>$0.025</td>
<td>$0.0034</td>
</tr>
<tr>
<td>2017-11-27</td>
<td>3796</td>
<td>2</td>
<td>0.05%</td>
<td>$0.01</td>
<td>$0.0026</td>
</tr>
<tr>
<td>2017-11-26</td>
<td>4005</td>
<td>2</td>
<td>0.05%</td>
<td>$0.01</td>
<td>$0.0025</td>
</tr>
<tr>
<td>2017-11-25</td>
<td>2070</td>
<td>2</td>
<td>0.1%</td>
<td>$0.01</td>
<td>$0.0048</td>
</tr>
<tr>
<td>2017-11-24</td>
<td>1016</td>
<td>6</td>
<td>0.59%</td>
<td>$0.03</td>
<td>$0.0295</td>
</tr>
<tr>
<td>2017-11-23</td>
<td>1503</td>
<td>4</td>
<td>0.27%</td>
<td>$0.02</td>
<td>$0.0133</td>
</tr>
<tr>
<td>2017-11-22</td>
<td>1665</td>
<td>11</td>
<td>0.66%</td>
<td>$0.055</td>
<td>$0.033</td>
</tr>
<tr>
<td>2017-11-21</td>
<td>1340</td>
<td>10</td>
<td>0.75%</td>
<td>$0.05</td>
<td>$0.0373</td>
</tr>
<tr>
<td>2017-11-20</td>
<td>1489</td>
<td>13</td>
<td>0.87%</td>
<td>$0.065</td>
<td>$0.0437</td>
</tr>
<tr>
<td>2017-11-19</td>
<td>1745</td>
<td>5</td>
<td>0.29%</td>
<td>$0.025</td>
<td>$0.0143</td>
</tr>
<tr>
<td>2017-11-18</td>
<td>962</td>
<td>5</td>
<td>0.52%</td>
<td>$0.025</td>
<td>$0.026</td>
</tr>
<tr>
<td>2017-11-17</td>
<td>779</td>
<td>8</td>
<td>1.03%</td>
<td>$0.04</td>
<td>$0.0513</td>
</tr>
</table>
</div>
这里的问题是它使用相同数字的数字正常工作但没有不同的数字位数。
例如,如果列包含:1, 5, 3
按预期排序。 1, 3, 5
&amp; 5, 3, 1
但如果该列包含:5, 3, 11
它被排序为:11, 3, 5
&amp; 5, 3, 11
如何正确排序?
答案 0 :(得分:0)
由于您有许多不同的格式,您可能想要做的是尝试提取数字的数字部分。
您可以尝试使用RegExp执行此操作,检查常用数字模式,然后解析为简单数字。如果我正在设计这个,我可能会为每种支持的格式提供一系列不同的匹配和转换函数。
这样的事情:
const patterns = [
{ test: /\$[0-9\.,]+/, transform: str => parseFloat(str.replace(/[$,]/g, '')) },
{ test: /[0-9\.,]+%/, transform: str => parseFloat(str.replace(/[%,]/g, '')) }
];
const convert = str => {
const pattern = patterns.find(({ test }) => test.test(str));
return pattern && pattern.transform(str) || str;
};
const converted = ['$1,234.56', '1,234.56%', 'not a num'].map(str => convert(str));
console.log(converted);
&#13;
然后,对于每个字段,在所有模式中运行它,直到找到匹配项,转换它们,然后进行数字排序。您也可以保留那些不会被转换为字符串的字符串,并让它们为那些字符串排序。
在您的代码中,如果您使用了我喜欢的内容,您只需将比较行更改为以下内容:
if (convert(x.innerHTML.toLowerCase()) > convert(y.innerHTML.toLowerCase()))
此外,日期提示:我建议将日期转换为时间戳或通用格式(例如YYYY-MM-DD HH:MM:SS
,这是最大到最小),这将允许您正确比较和排序多个日期格式在一列中。
以下是原始答案,其中没有说明带有数字的符号。
您的问题是您正在进行字符串比较而不是数字比较。
字符串比较将对字符串数字进行排序,就像字母表一样。例如,任何以1开头的东西总会出现在以2开头的任何东西之前,即使它是&#34; 1365872685623876723&#34;反对&#34; 2&#34;。
相反,请更改这些行:
x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()
首先将parseInt()
解析为数字:
parseInt(x.innerHTML.toLowerCase()) > parseInt(y.innerHTML.toLowerCase())
这会让它做一个数字排序。