Search code examples
javascriptarrayssortingvue.jslodash

Javascript custom sort with special characters dash (-) and underscore (_)


I am trying to do a custom sort like below order

  1. special character ( - first, _ last)
  2. digit
  3. alphabets

For example, if I sort below

var words = ['MBC-PEP-1', 'MBC-PEP01', 'MBC-PEP91', 'MBC-PEPA1', 'MBC-PEPZ1', 'MBC-PEP_1'];

result should be

MBC-PEP-1,MBC-PEP_1,MBC-PEP01,MBC-PEP91,MBC-PEPA1,MBC-PEPZ1

by using my code the result is below

"MBC-PEP-1", "MBC-PEP01", "MBC-PEP91", "MBC-PEP_1", "MBC-PEPA1", "MBC-PEPZ1"

but I need the above sorting order, not sure how to achieve it.

function MySort(alphabet)
{
    return function(a, b) {
        var lowerA = a.toLowerCase()
        var lowerB = b.toLowerCase()
        var index_a = alphabet.indexOf(lowerA[0]),
        index_b = alphabet.indexOf(lowerB[0]);

        if (index_a === index_b) {
            // same first character, sort regular
            if (a < b) {
                return -1;
            } else if (a > b) {
                return 1;
            }
            return 0;
        } else {
            return index_a - index_b;
        }
    }
}

var items = ['MBC-PEP-1', 'MBC-PEP01', 'MBC-PEP91', 'MBC-PEPA1', 'MBC-PEPZ1', 'MBC-PEP_1'],
sorter = MySort('-_0123456789abcdefghijklmnopqrstuvwxyz');

console.log(items.sort(sorter));


Solution

  • I ported an answer from here to JavaScript, which does what you want without using recursion or anything overly complicated:

    function MySort(alphabet) {
        return function (a, b) {
           a = a.toLowerCase();
           b = b.toLowerCase();
           var pos1 = 0;
           var pos2 = 0;
           for (var i = 0; i < Math.min(a.length, b.length) && pos1 == pos2; i++) {
              pos1 = alphabet.indexOf(a[i]);
              pos2 = alphabet.indexOf(b[i]);
           }
    
           if (pos1 == pos2 && a.length != b.length) {
               return o1.length - o2.length;
           }
    
           return pos1 - pos2;
        };
    }
        
    var items = ['MBC-PEP-1', 'MBC-PEP01', 'MBC-PEP91', 'MBC-PEPA1', 'MBC-PEPZ1', 'MBC-PEP_1'],
    sorter = MySort('-_0123456789abcdefghijklmnopqrstuvwxyz');
    
    console.log(items.sort(sorter));