Skip to content

Instantly share code, notes, and snippets.

@bmcminn
Last active January 13, 2020 22:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bmcminn/4bd71604bf91dde8b4d1e198c4e66560 to your computer and use it in GitHub Desktop.
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.
/**
* 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