0

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?

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

4 Answers 4

2

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>

Sign up to request clarification or add additional context in comments.

4 Comments

@SumitDeshpande NOTE: my answer only for string with max length = 3
Is there is any way to make it generic with any max length?
@SumitDeshpande in this line new Array(4-str.length) - 4 is max len+1 so you can use some parameter for that
@SumitDeshpande add some kind of generic in my updated answer
0

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;

}

2 Comments

'a1` - string, and b1 - string, a1-b1 equals NaN
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.
0

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

2 Comments

Is your answer inn ES6?
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.
-1

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

answer here,

weight: A < + & AAA < AA+

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.