Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I have an array that I need to sort-

var array1 = ["AAA","BB","B+","AA+","CC","AA-","B","A","AA"];

After applying filter/sort I want something like –

var array1 = ["AAA","AA+","AA","AA-","A","BB","B+","B","CC"];

Here alphabets having higher precedence over operator like after soring AAA should come before AA+

How can I do it?

share|improve this question
2  
You can write your own sorting function, the sort function on arrays accepts an optional custom comparator, see MDN. –  doldt Mar 11 at 7:17
    
it all possibly variants or possibly something like "AAB" or "BC+"? –  Grundy Mar 11 at 8:19
    
Yes we do have variants with mix alphabets –  Sumit Deshpande Mar 11 at 9:06
    
what possibly max string length? i mean how many symbols in one string like 'AAA' or 'AAAAAAAA' etc, or it unlimit? –  Grundy Mar 11 at 9:15
    
NOTE: my answer only for string with max length = 3 –  Grundy Mar 11 at 9:22

4 Answers 4

up vote 2 down vote accepted

As say above you need pass custom compare function to sort. Something like this

function s(a,b){
  function normalize(str){
    return str.concat(new Array(4-str.length).join(';')).replace(/[A-Z+-]/g, function($1){
      return replacer[$1] ? replacer[$1] : $1;
    });
  }

  var replacer = {
    'A' : '1',
    'B' : '2',
    'C' : '3',
    '+' : ':',
    '-' : '<'
  },

  ar = normalize(a),
  br = normalize(b);

  return ar > br ? 1
       : ar < br ? -1
       : 0;
}

var array1 = ["AAA","BB","B+","AA+","CC","AA-","B","A","AA"];

function s(a,b){
  function normalize(str){
    return str.concat(new Array(4-str.length).join(';')).replace(/[A-Z+-]/g, function($1){
      return replacer[$1] ? replacer[$1] : $1;
    });
  }
  
  var replacer = {
    'A' : '1',
    'B' : '2',
    'C' : '3',
    '+' : ':',
    '-' : '<'
  },
  
  ar = normalize(a),
  br = normalize(b);
  
  return ar > br ? 1
       : ar < br ? -1
       : 0;
}

document.getElementById('before').innerHTML = 'unsorted: ' + array1.join();

array1.sort(s);

document.getElementById('result').innerHTML = 'sorted: ' + array1.join();
<span id="before"></span><br>
<span id="result"></span>

UPDATE: a bit more generic

function sorting(maxLen) {
  return function s(a, b) {
    function checkLength(str, maxlen) {
      if (str.length > maxlen) {
        throw new Error('string: "' + str + '" (' + str.length + ') too long, max len: ' + maxlen);
      }
    }

    function normalize(str, maxlen) {
      return str.concat(new Array(maxlen + 1 - str.length).join(';')).replace(/[A-Z+-]/g, function($1) {
        return replacer[$1] ? replacer[$1] : $1;
      });
    }

    checkLength(a, maxLen);
    checkLength(b, maxLen);

    var replacer = {
        'A': '1',
        'B': '2',
        'C': '3',
        '+': ':',
        '-': '<'
      },
      ar = normalize(a, maxLen),
      br = normalize(b, maxLen);

    return ar > br ? 1 : ar < br ? -1 : 0;
  }
}

and use it function like

array1.sort(sorting(array1.reduce(function(a,b){return Math.max(a, b.length);},0))) 

var array1 = ["AAAA", "BB", "BBBB+", "AAA+", "CC", "AA-", "BBBB", "A", "AA"];
var array2 = ["AAAA", "BB", "BBBBB+", "AAA+", "CC", "AA-", "BBBB", "A", "AA"];

function sorting(maxLen) {
  return function s(a, b) {
    function checkLength(str, maxlen) {
      if (str.length > maxlen) {
        throw new Error('string: "' + str + '" (' + str.length + ') too long, max len: ' + maxlen);
      }
    }

    function normalize(str, maxlen) {
      return str.concat(new Array(maxlen + 1 - str.length).join(';')).replace(/[A-Z+-]/g, function($1) {
        return replacer[$1] ? replacer[$1] : $1;
      });
    }

    checkLength(a, maxLen);
    checkLength(b, maxLen);

    var replacer = {
        'A': '1',
        'B': '2',
        'C': '3',
        '+': ':',
        '-': '<'
      },
      ar = normalize(a, maxLen),
      br = normalize(b, maxLen);

    return ar > br ? 1 : ar < br ? -1 : 0;
  }
}

function test(witherror, arr, maxlen) {
  document.getElementById(witherror + 'before').innerHTML = 'unsorted: ' + arr.join();

  try {

    arr.sort(sorting(maxlen||arr.reduce(function(a,b){return Math.max(a, b.length);},0)));

    document.getElementById(witherror + 'result').innerHTML = 'sorted: ' + arr.join();

  } catch (e) {

    document.getElementById(witherror + 'result').innerHTML = e;

  }
}

test('', array1,5);
test('e', array2,5);
test('a', array2);
<span>sample with error, string is too long</span>
<br>
<span id="ebefore"></span>
<br>
<span id="eresult"></span>
<hr>
<span>sample without error, maxlen = 5</span>
<br>
<span id="before"></span>
<br>
<span id="result"></span>
<hr>
<span>sample without error</span>
<br>
<span id="abefore"></span>
<br>
<span id="aresult"></span>

share|improve this answer
    
Thanks it works :) –  Sumit Deshpande Mar 11 at 9:22
    
@SumitDeshpande NOTE: my answer only for string with max length = 3 –  Grundy Mar 11 at 9:22
    
Is there is any way to make it generic with any max length? –  Sumit Deshpande Mar 11 at 9:26
    
@SumitDeshpande in this line new Array(4-str.length) - 4 is max len+1 so you can use some parameter for that –  Grundy Mar 11 at 9:46
    
@SumitDeshpande add some kind of generic in my updated answer –  Grundy Mar 11 at 10:43

You will need to define a custom compare function and pass it to the sort

array.sort(myfunc)

The function should return a negative, zero, or positive value, depending on the arguments . Example function below

myfunc = function(a, b){
    //alphabet to be compared
    a1 = a.replace(/^[A-Z]+/,'');
    b1 = b.replace(/^[A-Z]+/,'');

    // in cases where alphabet are same , compare the full string.
    if(a1==b1 ){
         a1 = a;
         b1 = b;
    }
   if ( a1 < b1 ) return -1;
   if ( a1 > b1 ) return 1;
   return 0;

}
share|improve this answer
    
'a1` - string, and b1 - string, a1-b1 equals NaN –  Grundy Mar 11 at 7:51
    
thanks @grundy, corrected that for javascript. –  arkoak Mar 11 at 7:58
    
By using above function I am getting pattern as - A,AA,AAA,B,BB,CC,AA+,B+,AA- which is not matching with the expected result. –  Sumit Deshpande Mar 11 at 8:10

Try below custom function for your sort:

array1.sort(mySort);

function mySort(a,b){  

        var A = a;
        var B = b;
        if (A < B) {
            return -1;
        }
        else if (A > B) {
            return 1;
        }
        else {
            return 0;
        }
    }
share|improve this answer
    
Is your answer inn ES6? –  Derek 朕會功夫 Mar 11 at 7:44
    
Yes. I have updated for Javascript. –  Mustafa Mar 11 at 8:01
    
By using above function I am getting pattern as - A,AA,AA+,AA-,AAA,B,B+,BB,CC which is not matching with the expected result. –  Sumit Deshpande Mar 11 at 8:11

https://en.wikipedia.org/wiki/ASCII

answer here,

weight: A < + & AAA < AA+

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.