Sometimes it is nice to sort arrays word-wise in Javascript.
This means sorting not the entire column value,
/**
* Summary: Sorts alphabetaically word-wise to be used in e.g. a Select2Js control. Specify the n-word to start sorting with.
*
* Alphabetically sorts by each word
* @param {Number} startWordIndex The 'n-word' to begin sorting with *
* @param {boolean} isAscending The direction of sorting - true means ascending, false means descending
* @return {type} Return sort comparison value. If 0, the sorting is tie, if < 0 the element a preceeds b
*/
(function () {
var sortFunction = function sortFunctionTemplate(isAscending, startWordIndex, valueSelector, a, b) {
var aValue = valueSelector(a);
var bValue = valueSelector(b);
var astripped = aValue.split(' ');
var bstripped = bValue.split(' ');
var wordLength = Math.min(astripped.length, bstripped.length);
var compareValue = 0;
for (var i = startWordIndex; i < wordLength; i++) {
compareValue = astripped[i].localeCompare(bstripped[i]);
if (compareValue !== 0) {
break;
}
}
if (compareValue === 0) {
if (astripped.length > bstripped.length) {
compareValue = 1;
} else if (astripped.length < bstripped.length) {
compareValue = 1;
}
}
return compareValue * (isAscending ? 1 : -1);
};
if (typeof (Array.prototype.sortWordwise) === 'undefined') {
// ReSharper disable once NativeTypePrototypeExtending
Array.prototype.sortWordwise = function sortWordwise(startWordIndex, isAscending, valueSelector) {
if (valueSelector === null) {
valueSelector = function (item) {
return item;
};
}
//console.log('sorterer word-wise... ');
return this.sort(sortFunction.bind(this, isAscending, startWordIndex, valueSelector));
};
}
})();
Example how to use this method:
Here we use the Select2.js jQuery plugin to do our custom sorting to sort word-wise. I only consider the text after the ':' in my specific use case and I supply the starting index - sorting by the nth-word 1 (i.e. second word and so on) and supply a value selector function also. Select2.Js also retrieves a matcher function to specify the matching to be done case-insensitive (the find item in list function of the select 2 js control in this specific case).
$('.stentGraftfabrikatpicker').select2({
width: "element",
sortResults: function(data) {
var velgVerdi = data[0];
var ret = [velgVerdi];
var dataToBeSorted = data.splice(1);
return ret.concat(
dataToBeSorted.sortWordwise(1, true, function(item) {
var value = item.text;
return value.indexOf(':') >= 0 ? value.substring(value.indexOf(':') + 1) : value;
})
);
},
matcher: function(term, text) {
return text.toUpperCase().indexOf(term.toUpperCase()) >= 0;
},
allowClear: true
});