0

I am trying to sort an array of names into least to greatest order. Unfortunately JavaScript's .sort() will not work because it has underscores and letters in it.

I have this code:

var array = new Array("S1_FORM", "S2_FORM", "S3_2_FORM", "S3_FORM", "S3_3_FORM", "S4_FORM");
var SortedArray = array.sort();

This should sort it to be like:

S1_FORM, S2_FORM, S3_FORM, S3_2_FORM, S3_3_FORM, S4_FORM

Here's a jsdfiddle:

Jordan.J.D
  • 7,999
  • 11
  • 48
  • 78
Dylan Cross
  • 5,918
  • 22
  • 77
  • 118
  • I am not sure what sorting rule you want. Is 3_2 representing 3.2? Could there be a 3_10? Would that be ordered before 3_1 or after? – Billy Moon Jul 23 '15 at 18:18
  • 1
    No, stripping the `_` won't help. Rather, you seem to want to sort digits (`2`, `3`) after letters (`F`). Have a look at [Sort Array Elements (string with numbers), natural sort](http://stackoverflow.com/q/15478954/1048572) on how you might do that. – Bergi Jul 23 '15 at 18:19
  • Yes, I only want to sort based on the numbers. 1, 2, 3, 3_2, 3_3 – Dylan Cross Jul 23 '15 at 18:19
  • @Bergi yeah i just noticed that stripping _ would only make it worse. It would be more like 3, 3.1, 3.2, etc. – Dylan Cross Jul 23 '15 at 18:20

3 Answers3

2

Your sort is a bit tricky since the _FORM keeps it from being just a straightforward lexicographical sort.

Try this:

var SortedArray = array.sort(function(a, b){
                    a = a.slice(0, -5);
                    b = b.slice(0, -5); 
                    return a < b ? -1 : (a > b) ? 1 : 0;
                  });
Shannon Poole
  • 856
  • 5
  • 16
1

I believe you want a custom sort comparison function. See this post: How to define custom sort function in javascript?

Community
  • 1
  • 1
SHIELDHEAD
  • 45
  • 2
  • 6
0

As SHIELDHEAD suggested, you can pass a custom comparator function into Array.sort() when you want to sort by different rules than the default alphabetical/ordinal rules.

The format of the comparator function is as follows:

function(a,b){
     // if a should be before b, return -1
     // if b should be before a, return 1
     // if they are equal, return 0
     return a < b ? -1 : a > b ? 1 : 0;
}

In your case, I believe what your comparator function will need to do is grab the substring between "S" and "F" in your strings and compare those.

You can get that substring using regex: a = a.match(/(?!S)([0123456789_])+(?!F)/g);

Here's the working code:

var array = new Array("S1_FORM", "S2_FORM", "S3_2_FORM", "S3_FORM", "S3_3_FORM", "S4_FORM");
array.sort(function(a,b){
 a = a.match(/(?!S)([0123456789_])+(?!F)/g);
 b = b.match(/(?!S)([0123456789_])+(?!F)/g);
 return a < b ? -1 : a === b ? 0 : 1;
});
document.getElementById("output").innerHTML = JSON.stringify(array);
<div id="output"/>

EDIT: Also note that the sort() function changes the original array, so you don't need to create a separate variable to store the sorted array.

Thriggle
  • 7,009
  • 2
  • 26
  • 37