JSFiddle - React, Tailwind, and code Playground
by cdaringe
HTML
<h1>Sensible String-o-Numeric Sorter</h1>
<p>The following sorts strings that are mixed with numbers by actually factoring in the value of the number s.t. the sort order reflects that value.</p>
<p>If asked to sort the following:</p>
<ol>
<li>Week 1</li>
<li>Week 10</li>
<li>Week 2</li>
</ol>
<p>A normal js array sort will output results in THAT order. This sorter actually places the numbers in order. Play with the test data!</p>
<div class="log">
<h3>Log</h3>
<ul id="log"></ul>
</div>
CSS
.log{
background-color:#FFEAB6;
border-radius:5px;
font-family:"Helvetica", Arial;
padding: 10px;
}
JavaScript
function post(txt){
var newItem = document.createElement("li");
newItem.innerHTML += txt;
document.getElementById('log').appendChild(newItem);
}
// split @numbers credit: http://jsfiddle.net/5WJ9v/
items = ["Week 1", "27str", "22str", "2str", 3, "Week 10", 1, "Week 2", 0, "week 11", 150, "1", -43.3, "0", "Week 10 POST-JUNK", "Week 103 POSTFIX-JUNK", "Week 103 POSTFIX-JUNK 10", "Week 103 POSTFIX-JUNK 2"];
// items = ["27str", "2str", "22str"];
items.sort(function (a, b) {
if (!isNaN(a) && !isNaN(b)) return a - b;
else if (!isNaN(a) && isNaN(b)) return -1;
else if (isNaN(a) && !isNaN(b)) return 1;
else if (typeof a === "string" && typeof b === "string") {
var regex = /(\d+)/g,
aSplit = a.split(regex),
bSplit = b.split(regex),
aBlock, bBlock,
aBlockNum, bBlockNum;
for (var ndx = 0; ndx < aSplit.length; ++ndx) {
if (bSplit[ndx] !== undefined) {
aBlock = aSplit[ndx];
bBlock = bSplit[ndx];
} else {
return 1; // b is shorter, thus put it first
}
if (aBlock !== bBlock) {
// Check & compare numeric
aBlockNum = parseInt(aBlock,10);
bBlockNum = parseInt(bBlock,10);
if (aBlockNum && bBlockNum) return aBlockNum - bBlockNum;
if (aBlockNum && !bBlockNum) return -1;
if (!aBlockNum && bBlockNum) return 1;
// String compare
if (aBlock < bBlock) return -1;
if (aBlock > bBlock) return 1;
// if blocks ===, proceed to next block
}
}
return 0; // strings were equal
} else {
throw new Error("Invalid data passed to be sorted!");
}
});
items.forEach(post);
console.dir(items);