我有一个按字母顺序排序行的功能,它工作得很好,但如果它包含数字,它会将它排序为a1,a10,a11,...,a2,a20,...,a3而不是a1,a2 ,等等。
function sort(element) {
var sortableList = element;
var listitems = $('tr', sortableList);
listitems.sort(function (a, b) {
return ($(a).find('td.myclass').text().toUpperCase() > $(b).find('td.myclass').text().toUpperCase()) ? 1 : -1;
});
sortableList.append(listitems);
}
尝试使用此代码构成以下示例。还没有工作:
function sort(element) {
var sortableList = element;
var listitems = $('tr', sortableList);
var word = /[a-z]/i,
digit = /\d+/;
listitems.sort(function (a, b) {
return +$(a).find('td.myclass').text().match(digit)[0] > +$(b).find('td.myclass').text().match(digit)[0] ? 1 : -1;
}).sort(function (a, b) {
return $(a).find('td.myclass').text().match(word)[0] > $(b).find('td.myclass').text().match(word)[0] ? 1 : -1;
});
sortableList.append(listitems);
}
错误:null is not an object (evaluating '$(b).find('td.myclass').text().match(digit)[0]')
答案 0 :(得分:2)
我认为这应该按预期工作,无论文本的复杂程度如何......
function sort(sortableList) {
$(sortableList).append([].slice.call($('tr', sortableList)).map(function (e) {
return { element: e, values: ($(e).find('td').text().toUpperCase() || '').match(/([A-Z]+|\d+)/g) };
}).sort(function (aa, bb) {
var valuesA = aa.values ||[];
var valuesB = bb.values ||[];
var len = Math.min(valuesA.length, valuesB.length);
for (var i = 0; i < len; i++) {
var a = valuesA[i];
var b = valuesB[i];
if (a === b) {
continue;
}
var aIsNum = !isNaN(parseInt(a));
var bIsNum = !isNaN(parseInt(b));
if (aIsNum && bIsNum) {
return parseInt(a) - parseInt(b);
}
if (!(aIsNum && bIsNum)) {
return a > b ? 1 : -1;
}
if (aIsNum) {
return -1;
}
return 1;
}
return valuesA.length - valuesB.length;
}).map(function (e) {
return e.element;
}));
document.getElementById('msg').textContent = 'Sorted';
}
setTimeout(function () {
return sort(document.querySelector('table'));
}, 2000);
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span id="msg">Wait for it ....</span>
<table>
<tr>
<td>a100</td>
</tr>
<tr>
<td>a10</td>
</tr>
<tr>
<td>b100</td>
</tr>
<tr>
<td>a20</td>
</tr>
<tr>
<td>a1</td>
</tr>
<tr>
<td>a2</td>
</tr>
<tr>
<td style="background:red"></td>
</tr>
<tr>
<td>5</td>
</tr>
<tr>
<td>a</td>
</tr>
<tr>
<td>b1</td>
</tr>
</table>
&#13;
答案 1 :(得分:0)
试试这个
"use strict";
let myArr = ['a1', 'c', 'c56','a', 'ac2', 'ab21', 1, '5a', 6, 'A16', 'b', 3, 'a3', 'abc'];
let result = [];
function compareNumeric(a, b) {
return parseInt(a) - parseInt(b);
}
function compareStr(a, b) {
return a.toUpperCase() > b.toUpperCase();
}
function compareStrNum(a, b) {
if (a.match(/[a-z]+/i)[0].toUpperCase() === b.match(/[a-z]+/i)[0].toUpperCase()) {
if (a.match(/\d+/) === null) {
return 0;
}
return +a.match(/\d+/)[0] - +b.match(/\d+/)[0];
}
}
function compare(arr) {
let numeric = [];
let str = [];
for (let i = 0, max = arr.length; i < max; i++) {
if (parseInt(arr[i])) {
numeric.push(arr[i]);
} else {
str.push(arr[i]);
}
}
numeric = numeric.sort(compareNumeric);
str.sort(compareStr)
.sort(compareStrNum);
result = result.concat(numeric);
result = result.concat(str);
}
compare(myArr);
console.log(result);