Friday, 15 November 2019

Sorting array word-wise in Javascript

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
    });

No comments:

Post a comment