我想根据版本号对表格进行排序,最高在顶部。如果单元格以“v”开头,后跟一个数字,则它被视为版本号。否则,它应该按字母顺序排列在表格的底部。
结果目前正是我想要的方式,除了 v2.0 应该在 v2a 之前,v2a 应该在 v2b 之前。我知道我parseFloat()
正在搞砸,但我怎样才能以更好的方式做到这一点?
function sortTable(table, order, selector, target) {
selector = selector || 'th:first-child, td:first-child';
var asc = order === 'asc';
target = target || '';
var tbody = table.querySelector('tbody') || table;
var nodes = tbody.querySelectorAll('tr');
var sortedNodes = Array.prototype.slice.apply(nodes);
sortedNodes.sort(function (a, b) {
var textA = a.querySelector(selector).textContent;
var textB = b.querySelector(selector).textContent;
if( target == 'versions' )
{
if (textA.match(/^v\d.*/i)) {
textA = parseFloat(textA.substr(1));
}
if (textB.match(/^v\d.*/i)) {
textB = parseFloat(textB.substr(1));
}
}
result = textA - textB;
if (isNaN(result))
{
return (asc && textB.toString() != '' ) ? textA.toString().localeCompare(textB) : textB.toString().localeCompare(textA);
}
else
{
return (asc) ? -result : result;
}
});
tbody.textContent = '';
for (var i = 0; i < sortedNodes.length; i++) {
tbody.appendChild(sortedNodes[i]);
}
}
sortTable(document.getElementById('versions'), 'asc', '', 'versions');
<table id="versions">
<tbody>
<tr><td>Text</td></tr>
<tr><td>v2b</td></tr>
<tr><td>v3.0</td></tr>
<tr><td>v2a</td></tr>
<tr><td></td></tr>
<tr><td>v2.0</td></tr>
<tr><td>No version number</td></tr>
<tr><td>v1.0 Work in Progress</td></tr>
</tbody>
</table>
您可以使用 RegEx 拆分版本号和后缀,以确保正确处理数字部分。
我不是 100% 确定这个片段涵盖了所写的所有可能的情况。它处理您的样本数据,并且可以轻松调整以处理存在的边缘情况。
为了排序的清晰性和简单性,我省略了 DOM 内容。 除了原始文本值之外,我还更新了代码片段以演示基本的表格排序。
const values = [
"Text",
"v2b",
"v3.0",
"v2a",
"",
"v2.0",
"v30.4alpha",
"No version number",
"v1.0 Work in Progress",
];
// regex to separate the numeric version from the suffix
// e.g. "v2.0a" => ["2.0", "a"]
const version = /v(\d+(?:\.\d+)*)(.*)/;
function getSortValue (item) {
if (item == null ) {
return item;
}
// might want to do something more robust here.
// if it's not a string this assumes it's a tr
// and the first cell has the text we care about.
return typeof item === "string"
? item
: item.firstChild.textContent;
}
function sort(av, bv) {
const a = getSortValue(av);
const b = getSortValue(bv);
if (b && !a) {
return 1;
}
if (a && !b) {
return -1;
}
// get the numeric version and suffix for each item,
// OR'd with [] for cases where the regex doesn't match
const [, aVersion = 0, aSuffix = ''] = version.exec(a) || [];
const [, bVersion = 0, bSuffix = ''] = version.exec(b) || [];
// sort on the numeric portion
const versionDiff = parseFloat(bVersion) - parseFloat(aVersion);
// if the numeric versions are the same
// sort on the suffix
if (versionDiff === 0) {
return aSuffix.localeCompare(bSuffix) || a.localeCompare(b);
}
// numeric versions are different; sorting them is enough.
return versionDiff;
}
// sort raw text values
document.querySelector('pre').innerHTML = JSON.stringify(values.sort(sort), null, 2);
// sort table rows
const rows = Array.from(document.querySelectorAll('tr'));
rows.sort(sort);
const tbody = rows[0].parentElement;
rows.forEach(r => tbody.append(r));
table {
width: 100%;
font-family: monospace;
font-size: 14px;
}
td {
padding: 4px 8px;
}
tr:nth-child(2n - 1) {
background: #eee;
}
<table id="versions">
<tbody>
<tr><td>Text</td></tr>
<tr><td>v2b</td></tr>
<tr><td>v3.0</td></tr>
<tr><td>v2a</td></tr>
<tr><td></td></tr>
<tr><td>v2.0</td></tr>
<tr><td>No version number</td></tr>
<tr><td>v1.0 Work in Progress</td></tr>
</tbody>
</table>
<pre></pre>
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句