# Shorten a custom JS sort function

I have a sort function that needed to sort in a certain way. That position was sorted by mobile-top first, then empty position followed by mobile-bottom. Then on these I needed to sort by their priority, with priority 1, 2 and then blank.

  widgetInfo = [
['box1','mobile-bottom',''],
['box2','mobile-top','priority-1'],
['box3','mobile-top',''],
['box3','mobile-top',''],
['box4','mobile-bottom',''],
['box2','mobile-top','priority-1'],
['box5','mobile-top','priority-2'],
['box6','','']],
['box5','mobile-top','priority-2'];

var newArray = widgetInfo.sort(function(a, b){

if(a[1] == 'mobile-top'){
if(b[1] == 'mobile-bottom'){
return -1;
}
else if(b[1] == 'mobile-top'){

if(a[2] == 'priority-1'){

if(b[2] == 'priority-1'){
return 0;
}
else if(b[2] == 'priority-2'){
return -1;
}
else{
return -1;
}
}

else if(a[2] == 'priority-2'){

if(b[2] == 'priority-1'){
return 1;
}
else if(b[2] == 'priority-2'){
return 0;
}
else{
return -1;
}
}

else{
return 1;
}

}
else{
return -1;
}
}
if(a[1] == 'mobile-bottom'){
if(b[1] == 'mobile-top'){
return 1;
}
else if(b[1] == 'mobile-bottom'){
return 0;
}
else{
return 1;
}
}

});


It seems like one heck of a lot of code to do this and I'm certain there will be better ways. Any suggestions?

first check if the priority 1 are unequal and then return 1/-1 accordingly otherwise check priority 2 and repeat

If you reach the end then all terms will be equal:

function(a, b){

if(a[1] != b[1]){
if(a[1] == 'mobile-bottom' || b[1]== '') //b[1] will be -top or empty => a<b
return 1;
else
return -1;
}

if(a[2]!=b[2]){
if(a[2] == 'priority-1' || b[2] == '') //b[2] will be -2 => a<b
return 1;
else if(
return -1;
}

return 0;
}


You can replace the test against string with functions that just check those values then this simplifies to

function(a, b){
var result = compareMobile(a[1], b[1]);

if(result != 0){
return result;
}

result = comparePriority(a[2], b[2]);

return result;
}


You can write a function to compare two "position" strings and a function to compare "priority" strings. Then a resulting comparison function could be written easily by calling the two already defined functions.

Now for the actual review, you don't need the if(b[1] == 'mobile-bottom') check in the if(a[1] == 'mobile-top') case, checking first if if(b[1] == 'mobile-top') is enough, in the other case, you can simply return -1.

Similarly, if(a[1] == 'mobile-bottom'), you only need to consider if(b[1] == 'mobile-bottom'), otherwise, you can simply return 1.

What about calculating a priority hash?

var mobilePrios = ['mobile-top', 'mobile-bottom'];

function calculatePriority(widgInf) {
return (mobilePrios.indexOf(widgInf[0]) + 2) * 4 + widgInf[1].replace('priority-', '') * 0.10;
}


the just call this for the two widgInfo - Elements you want to compare and order that by the value returned.