Last active
January 13, 2020 22:07
-
-
Save bmcminn/4bd71604bf91dde8b4d1e198c4e66560 to your computer and use it in GitHub Desktop.
Allows you to sort a colleciton of objects by any given property within those objects.
This file contains hidden or 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
/** | |
* Sorts a collection of objects based on a pipe-delimited list of sorting parameter config strings | |
* @param {array} collection Collection of objects | |
* @param {string} sortKeys Pipe separated string of sortable properties within the collection model and it's sort priorities: | |
* @param {string} invertCollection invert collection sort | |
* | |
* @schema sortKeys: '(string)keyName:(string)keyType:(string)invert|...' | |
* @example sortKeys: 'isOldData:boolean|orderTotal:number:invert|productName:string' | |
* | |
* @return {array} The sorted collection | |
*/ | |
export function sortCollection(collection, sortKeys = '', invertCollection = false) { | |
if (!Array.isArray(collection)) { | |
let msg = 'collection must be of type Array' | |
console.error(msg, collection) | |
throw new Error(msg) | |
} | |
const TABLE_SORT_DIRECTION = invertCollection ? -1 : 1 | |
// split sortKeys string by pipes | |
sortKeys.split('|') | |
// for each sortKey | |
.map((el) => { | |
if (el.trim().length === 0) { | |
return 0 | |
} | |
// split the sortKey into it's key and dataType | |
let parts = el.split(':') | |
let keyName = parts[0].trim() | |
let keyType = (parts[1] || 'string').trim().toLowerCase() // presume the type is a string if not defined | |
let invertColumn = (parts[2] || '').trim().toLowerCase() === 'invert' ? -1 : 1 // a 3rd config prop should invert the sort | |
// console.debug('sortCollection', parts) | |
// sort collection by sortKey | |
collection.sort((a, b) => { | |
let aProp = a[keyName] | |
let bProp = b[keyName] | |
// manipulate comparator data based on datatype | |
switch(keyType) { | |
case 'string': | |
// ensure the string is actually a string and not null | |
aProp = aProp ? aProp + '' : '' | |
bProp = bProp ? bProp + '' : '' | |
aProp = aProp.toLowerCase().trim() | |
bProp = bProp.toLowerCase().trim() | |
break; | |
case 'number': | |
case 'boolean': | |
case 'date': | |
default: | |
break; | |
} | |
let sortDir = 0 | |
if (aProp < bProp) sortDir = -1 * TABLE_SORT_DIRECTION * invertColumn | |
if (aProp > bProp) sortDir = 1 * TABLE_SORT_DIRECTION * invertColumn | |
// console.debug('sortCollection :: sortDir', sortDir, aProp, bProp, TABLE_SORT_DIRECTION, invertColumn) | |
return sortDir | |
}) | |
}) | |
return collection | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment