简体   繁体   中英

Sort array in ascending order

Array: var ranges = ["3-5", "1-4", "0-9", "10-10"];

I tried the following function:

ranges.sort();

// Output: 0-9,1-4,10-10,3-5

// Desired output: 0-9,1-4,3-5,10-10

Any idea how I can get to desired output?

If you want to sort by the first number, the approach is:

var desire = ranges.sort(function(a,b){return parseInt(a)-parseInt(b)});

Explanation: parseInt(a) just removes everything after the non-number, ie - and returns the number.

If you also want to make it sort by the first number properly if you have ranges starting with the same numbers (ie 3-5 and 3-7 ):

var desire = ranges.sort(function(a,b){
   return (c=parseInt(a)-parseInt(b))?c:a.split('-')[1]-b.split('-')[1]
});

Explanation: works as the first one until the first numbers are equal; then it checks for the second numbers (thanks Michael Geary for idea!)

If you want to sort by the result of equation, go for

var desire = ranges.sort(function(a,b){return eval(a)-eval(b)});

Explanation: eval(a) just evaluates the expression and passes the result.

Also, as mentioned by h2ooooooo , you can specify the radix to avoid unpredictable behavior (ie parseInt(a, 10) ).

One thing your test case doesn't exercise is ranges that begin with the same value but have different ending values, for example:

[ "3-5", "1-5", "1-4", "10-9", "0-9", "10-10" ];

Presumably you would want those sorted in this order:

[ "0-9", "1-4", "1-5", "3-5", "10-9", "10-10" ]

Here's a sort function that sorts by the beginning of each range, and secondarily by the end of each range. So if two ranges start with the same value, the range that ends earlier will sort first.

function sortRanges( range ) {
    return ranges.sort( function( a, b ) {
        var aSplit = a.split( '-' ), aStart = aSplit[0], aEnd = aSplit[1];
        var bSplit = b.split( '-' ), bStart = bSplit[0], bEnd = bSplit[1];
        return aStart - bStart ? aStart - bStart : aEnd - bEnd;
    });
}

var ranges = [ "3-5", "1-5", "1-4", "10-9", "0-9", "10-10" ];
console.log( sortRanges( ranges ) );

This logs the result above.

How it works: The sort() function calls a comparator function with two arguments which are two array elements to be compared. This function must return a negative, positive, or zero value to indicate the sort order for these two elements.

So we split each range to get its start and end values, and then simply subtract the start values. If the result is nonzero, we return it, or if it is zero we go on to subtract the end values and return that.

Subtracting two numeric values is an easy way to generate the negative/zero/positive result for this function. (Note that any negative or positive value will do.) And as a nice side effect, it also converts both values to numbers before the subtraction. That's why the code doesn't need parseInt() or anything like that.

One more boring answer:

 var r = /^(\\d+)-(\\d+)$/; var ranges = ['3-5', '1-4', '0-9', '10-10']; ranges.sort(function (a, b) { a = a.match(r); b = b.match(r); a = Math.abs(a[1] - a[2]); b = Math.abs(b[1] - b[2]); return b - a; }); document.write(ranges); 

Here's one more:

var ranges = ["3-5", "1-4", "0-9", "10-10"];

ranges.sort(function(a, b) {
 return a.split('-')[0] - b.split('-')[0];
});

console.log(ranges);

Output:

["0-9", "1-4", "3-5", "10-10"]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM