Last active
December 2, 2022 11:03
-
-
Save ksdev-pl/4e55a9f1195a6fb4ccd7758a81faadd4 to your computer and use it in GitHub Desktop.
Natural sort orderBy filter for vue.js #js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
naturalSort.insensitive = true; | |
Vue.filter('naturalOrderBy', function (arr, sortKey, reverse) { | |
if (!sortKey) { | |
return arr; | |
} | |
var order = (reverse && reverse < 0) ? -1 : 1; | |
return arr.slice().sort(naturalSort.bind(null, sortKey, order)); | |
}); | |
/* | |
* Natural Sort algorithm for Javascript - Version 0.8.1 - Released under MIT license | |
* Author: Jim Palmer (based on chunking idea from Dave Koelle) | |
* https://github.com/overset/javascript-natural-sort | |
* | |
* Modified for vue.js 1 | |
*/ | |
function naturalSort (sortKey, order, a, b) { | |
if (sortKey !== '$key') { | |
if (Vue.util.isObject(a) && '$value' in a) a = a.$value; | |
if (Vue.util.isObject(b) && '$value' in b) b = b.$value; | |
} | |
a = Vue.util.isObject(a) ? Vue.parsers.path.getPath(a, sortKey) : a; | |
b = Vue.util.isObject(b) ? Vue.parsers.path.getPath(b, sortKey) : b; | |
var re = /(^([+\-]?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?(?=\D|\s|$))|^0x[\da-fA-F]+$|\d+)/g, | |
sre = /^\s+|\s+$/g, // trim pre-post whitespace | |
snre = /\s+/g, // normalize all whitespace to single ' ' character | |
dre = /(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/, | |
hre = /^0x[0-9a-f]+$/i, | |
ore = /^0/, | |
i = function(s) { | |
return (naturalSort.insensitive && ('' + s).toLowerCase() || '' + s).replace(sre, ''); | |
}, | |
// convert all to strings strip whitespace | |
x = i(a), | |
y = i(b), | |
// chunk/tokenize | |
xN = x.replace(re, '\0$1\0').replace(/\0$/,'').replace(/^\0/,'').split('\0'), | |
yN = y.replace(re, '\0$1\0').replace(/\0$/,'').replace(/^\0/,'').split('\0'), | |
// numeric, hex or date detection | |
xD = parseInt(x.match(hre), 16) || (xN.length !== 1 && Date.parse(x)), | |
yD = parseInt(y.match(hre), 16) || xD && y.match(dre) && Date.parse(y) || null, | |
normChunk = function(s, l) { | |
// normalize spaces; find floats not starting with '0', string or 0 if not defined (Clint Priest) | |
return (!s.match(ore) || l == 1) && parseFloat(s) || s.replace(snre, ' ').replace(sre, '') || 0; | |
}, | |
oFxNcL, oFyNcL; | |
// first try and sort Hex codes or Dates | |
if (yD) { | |
if (xD < yD) { return -order; } | |
else if (xD > yD) { return order; } | |
} | |
// natural sorting through split numeric strings and default strings | |
for(var cLoc = 0, xNl = xN.length, yNl = yN.length, numS = Math.max(xNl, yNl); cLoc < numS; cLoc++) { | |
oFxNcL = normChunk(xN[cLoc] || '', xNl); | |
oFyNcL = normChunk(yN[cLoc] || '', yNl); | |
// handle numeric vs string comparison - number < string - (Kyle Adams) | |
if (isNaN(oFxNcL) !== isNaN(oFyNcL)) { | |
return isNaN(oFxNcL) ? order : -order; | |
} | |
// if unicode use locale comparison | |
if (/[^\x00-\x80]/.test(oFxNcL + oFyNcL) && oFxNcL.localeCompare) { | |
var comp = oFxNcL.localeCompare(oFyNcL); | |
var returnVal = comp / Math.abs(comp); | |
return (returnVal === 0 ? 0 : (returnVal === 1 ? order : -order)); | |
} | |
if (oFxNcL < oFyNcL) { return -order; } | |
else if (oFxNcL > oFyNcL) { return order; } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment