105 lines
2.5 KiB
JavaScript
105 lines
2.5 KiB
JavaScript
|
import { reach } from './reach.js';
|
||
|
|
||
|
/**
|
||
|
* Sort collection asc by some field.
|
||
|
*
|
||
|
* @param {String} field Field to sort by.
|
||
|
* @param {Array} collection Collection to sort.
|
||
|
* @return {Array} The sorted collection.
|
||
|
*/
|
||
|
const sortAsc = (field, collection) => {
|
||
|
return collection.sort(function(a, b) {
|
||
|
let s1 = reach(field, a);
|
||
|
let s2 = reach(field, b);
|
||
|
|
||
|
if (typeof s1 === 'string') {
|
||
|
s1 = s1.toLowerCase();
|
||
|
}
|
||
|
|
||
|
if (typeof s2 === 'string') {
|
||
|
s2 = s2.toLowerCase();
|
||
|
}
|
||
|
|
||
|
return naturalCompare(s1, s2);
|
||
|
}.bind(this));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sort collection desc by some field.
|
||
|
*
|
||
|
* @param {String} field Field to sort by.
|
||
|
* @param {Array} collection Collection to sort.
|
||
|
* @return {Array} The sorted collection.
|
||
|
*/
|
||
|
const sortDesc = (field, collection) => {
|
||
|
return collection.sort(function(a, b) {
|
||
|
let s1 = reach(field, a);
|
||
|
let s2 = reach(field, b);
|
||
|
|
||
|
if (typeof s1 === 'string') {
|
||
|
s1 = s1.toLowerCase();
|
||
|
}
|
||
|
|
||
|
if (typeof s2 === 'string') {
|
||
|
s2 = s2.toLowerCase();
|
||
|
}
|
||
|
|
||
|
return naturalCompare(s2, s1);
|
||
|
}.bind(this));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sort strings naturally.
|
||
|
*
|
||
|
* @version 1.4.0
|
||
|
* @date 2015-10-26
|
||
|
* @stability 3 - Stable
|
||
|
* @author Lauri Rooden (https://github.com/litejs/natural-compare-lite)
|
||
|
* @license MIT License
|
||
|
*
|
||
|
* @param {String} a
|
||
|
* @param {String} b
|
||
|
* @return {Number} -1, 1 or 0.
|
||
|
*/
|
||
|
const naturalCompare = (a, b) => {
|
||
|
let i;
|
||
|
let codeA;
|
||
|
let codeB = 1;
|
||
|
let posA = 0;
|
||
|
let posB = 0;
|
||
|
const alphabet = String.alphabet;
|
||
|
|
||
|
function getCode(str, pos, code) {
|
||
|
if (code) {
|
||
|
for (i = pos; code = getCode(str, i), code < 76 && code > 65;) ++i;
|
||
|
return Number(str.slice(pos - 1, i));
|
||
|
}
|
||
|
code = alphabet && alphabet.indexOf(str.charAt(pos));
|
||
|
return code > -1 ? code + 76 : ((code = str.charCodeAt(pos) || 0), code < 45 || code > 127) ? code
|
||
|
: code < 46 ? 65 // -
|
||
|
: code < 48 ? code - 1
|
||
|
: code < 58 ? code + 18 // 0-9
|
||
|
: code < 65 ? code - 11
|
||
|
: code < 91 ? code + 11 // A-Z
|
||
|
: code < 97 ? code - 37
|
||
|
: code < 123 ? code + 5 // a-z
|
||
|
: code - 63;
|
||
|
}
|
||
|
|
||
|
if ((a += '') != (b += '')) for (;codeB;) {
|
||
|
codeA = getCode(a, posA++);
|
||
|
codeB = getCode(b, posB++);
|
||
|
|
||
|
if (codeA < 76 && codeB < 76 && codeA > 66 && codeB > 66) {
|
||
|
codeA = getCode(a, posA, posA);
|
||
|
codeB = getCode(b, posB, posA = i);
|
||
|
posB = i;
|
||
|
}
|
||
|
|
||
|
if (codeA != codeB) return (codeA < codeB) ? -1 : 1;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
export { sortAsc, sortDesc, naturalCompare };
|