问题
I want to sort this javascript array:
[103,3,4,6,8,"8L",67,1,11,19,68,86,107,"9L"];
sort it by numbers and letters, so the result will look like this:
[1,3,4,6,8,"8L","9L",11,19,67,68,86,103,107];
When I try to use sort()
, it doesn't work:
[1,3,4,6,8,68,103,"8L",11,19,67,86,107,"9L"]; // 8L and 9L are in the wrong place
// correct wanted order
var correct = [1,3,4,6,8,"8L","9L",11,19,67,68,86,103,107];
document.body.innerHTML += '<b>correct wanted order:</b> <pre>' + JSON.stringify(correct) + '</pre>';
// array to order
var unordered = [103,3,4,6,8,"8L",67,1,11,19,68,86,107,"9L"];
document.body.innerHTML += '<b>array to order:</b> <pre>' + JSON.stringify(unordered) + '</pre>';
unordered = unordered.map(item => {
return item;
});
var ordered = unordered.sort(function(a, b) {
return a - b;
});
document.body.innerHTML += '<b>order attempt:</b> <pre>' + JSON.stringify(ordered) + '</pre>';
回答1:
You can do this easily using array .sort() & localeCompare() method by passing the {numeric: true}
option like:
var unordered = [103,3,4,6,8,"8L",67,1,11,19,68,86,107,"9L"];
var correct = unordered.sort((a,b) =>
a.toString().localeCompare(b.toString(), undefined, {numeric: true}))
console.log( correct )
.as-console-wrapper { max-height: 100% !important; top: 0; }
回答2:
It looks like you'll want to start by treating everything in your sort function like a string. Then split the numbers from the rest of the string and test them separately. Something like this:
const ordered = unordered.sort(function(a, b) {
// Break apart the assumed strings (Numbers then everything else)
const [, aNumber, aString] = `${a}`.match(/(\d*)(.*)/);
const [, bNumber, bString] = `${b}`.match(/(\d*)(.*)/);
// Test numbers
if(Number(aNumber) < Number(bNumber)) return -1;
if(Number(aNumber) > Number(bNumber)) return 1;
// Test letters if there is a tie
return aString < bString ? -1 : 1;
});
来源:https://stackoverflow.com/questions/61683362/sort-javascript-array-by-numbers-and-letters