-1

I have the following array and sort result:

['53-15-9', '53-15-10', '53-15-8'].sort() // => ["53-15-10", "53-15-8", "53-15-9"]

but I need to get the following result:

["53-15-8", "53-15-9", "53-15-10"];

How could I get desired result?

3
  • 3
    Convert them to numbers for the purposes of comparision Commented Jan 19, 2016 at 18:41
  • How to define custom sort function in javascript Commented Jan 19, 2016 at 18:46
  • you should check @Maxali's answer. Doesn't say much, but it's exactly what you need. Also - learn how to provide your own comparison function to sort. Check out the docs Commented Jan 19, 2016 at 18:51

6 Answers 6

4

To compare numbers instead of strings, first remove '-'. When you use arithmetic operation, JavaScript first coverts it to numbers.

'53-15-9'.replace(/-/g,'') gives '53159'. You can use closures in sort() to pass compare function that can simply subtract a from b. The following function will sort the array ascending:

    ['53-15-9', '53-15-10', '53-15-8'].sort(function(a,b){
        return a.replace(/-/g,'') - b.replace(/-/g,'')
    })

Update

As mentioned in the comments, '54-1-1' is less than '53-15-9'. We can change '54-1-1' to '54-01-01'. This only works in double digits. We can do it like:

function customSort(myArray) {
    myArray = myArray.map(function(a,b){
        var ar = a.split('-');

        return ar.map(function(arK, arV){return (arK<10)?'0'+arK : arK.toString();}).join('-');;
    })

    return myArray.sort(function(a,b){
        return a.replace(/-/g,'') - b.replace(/-/g,'')
    });  
}

customSort(['54-1-2','53-15-9', '53-15-10', '53-15-8']);
// => ["53-15-08", "53-15-09", "53-15-10", "54-01-02"]
Sign up to request clarification or add additional context in comments.

5 Comments

And without regex: return a.split('-').join('') - b.split('-').join('')
But if you add 54-1-1 it will be sorted at the beginning, and probably should be at the end.
@Oriol because its converting to numbers. and 5,411 is smaller than 531,519. \
@Maxali I know why. I was only noting this may be undesired.
@Oriol I updated to achieve this sort. Check the answer.
0

You can use a custom function for splitting and sorting the parts.

var array = ['53-15-9', '53-15-10', '53-15-8'];
array.sort(function (a, b) {
    var aa = a.split('-'),
        bb = b.split('-'),
        i, r = 0, l = Math.max(aa.length, bb.length);
    for (i = 0; !r && i < l; i++) {
        r = (aa[i] || 0) - (bb[i] || 0);
    }
    return r;
});

document.write('<pre>' + JSON.stringify(array, 0, 4) + '</pre>');

Comments

0
['53-15-9', '53-15-10', '53-15-8'].sort(function(a, b) {
  var aNum = parseInt(a.replace(/-/g, ''));
  var bNum = parseInt(b.replace(/-/g, ''));
  return aNum < bNum ? -1 : aNum > bNum ? 1 : 0;
});

Assuming you want to sort them in numerical order including all the sections, simply remove the -, parse them as an int and then sort the ints in a custom sort function.

Comments

0
var arr = ['53-15-9', '53-15-10', '53-15-8'];
arr.sort(function(a,b){ return a.replace(/-/g,'') - b.replace(/-/g,'') });  
console.log(arr);

output

["53-15-8", "53-15-9", "53-15-10"]

Comments

0

Try comparing every number separated by - using Array.prototype.every()

var arr = ["53-15-8", "53-15-9", "53-15-10"];

arr.sort(function(a, b) {
  var curr = a.split(/-/).map(Number);
  var next = b.split(/-/).map(Number);
  return curr.every(function(val, key) {return val <= next[key]}) ? a : b
});

console.log(JSON.stringify(arr))

5 Comments

['1', '2'] is sorted as ['2', '1']
@Oriol Yes, updating currently. .every() not returning expected results. Approach is to compare each number separated by "-"
@Oriol See updated post. Adjusted comparison operator to <= within .every()
Now ['1-2', '2-1'] is sorted as ['2-1', '1-2'].
@Oriol See updated post. Substituted returning a , b for -1, 1
0

You need to define your own custom sorting function. Here is an example:

['53-15-9', '53-15-10', '53-15-8','2', '53-14-4','53-15-99'].sort(function(a,b){ // a and b are elements of the array
  // split by - and convert values to number 
  a = a.split('-').map(function(val){return Number(val)}) 
  b = b.split('-').map(function(val){return Number(val)})

  // if one has less elements than another, we consider it should go first
  if(a.length != b.length) return a.length > b.length

  //else, one goes after another if one of its elements is greater than the others at that index
  return a.some(function(val, index){
      return val > b[index]
  }) == 0 ? -1 : 1   

})

//output: ["2", "53-14-4", "53-15-8", "53-15-9", "53-15-10", "53-15-99"]

1 Comment

Note you are returning booleans instead of numbers. false will be treated as 0, which means both values should be considered equal. I can't find any counterexample, but I'm not sure this is completely well-defined. If it isn't, the result of the sort will be implementation-dependent.

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.