Skip to content Skip to sidebar Skip to footer

How To Sort Strings In Javascript Numerically

I would like to sort an array of strings (in javascript) such that groups of digits within the strings are compared as integers not strings. I am not worried about signed or float

Solution 1:

I think this does what you want

function sortArray(arr) {
    var tempArr = [], n;
    for (var i in arr) {
        tempArr[i] = arr[i].match(/([^0-9]+)|([0-9]+)/g);
        for (var j in tempArr[i]) {
            if( ! isNaN(n = parseInt(tempArr[i][j])) ){
                tempArr[i][j] = n;
            }
        }
    }
    tempArr.sort(function (x, y) {
        for (var i in x) {
            if (y.length < i || x[i] < y[i]) {
                return -1; // x is longer
            }
            if (x[i] > y[i]) {
                return 1;
            }
        }
        return 0;
    });
    for (var i in tempArr) {
        arr[i] = tempArr[i].join('');
    }
    return arr;
}
alert(
    sortArray(["a1b3", "a10b11", "a10b2", "a9b2"]).join(",")
);

Solution 2:

Another variant is to use an instance of Intl.Collator with numeric option:

var array = ["a100","a20","a3","a3b","a3b100","a3b20","a3b3","!!","~~","9","10","9.5"];
var collator = new Intl.Collator([], {numeric: true});
array.sort((a, b) => collator.compare(a, b));
console.log(array);

Solution 3:

Assuming what you want to do is just do a numeric sort by the digits in each array entry (ignoring the non-digits), you can use this:

function sortByDigits(array) {
    var re = /\D/g;

    array.sort(function(a, b) {
        return(parseInt(a.replace(re, ""), 10) - parseInt(b.replace(re, ""), 10));
    });
    return(array);
}

It uses a custom sort function that removes the digits and converts to a number each time it's asked to do a comparison. You can see it work here: http://jsfiddle.net/jfriend00/t87m2/.

If this isn't what you want, then please clarify as your question is not very clear on how the sort should actually work.


Solution 4:

Use this compare function for sorting ..

function compareLists(a,b){
    var alist = a.split(/(\d+)/), // split text on change from anything to digit and digit to anything
        blist = b.split(/(\d+)/); // split text on change from anything to digit and digit to anything

    alist.slice(-1) == '' ? alist.pop() : null; // remove the last element if empty
    blist.slice(-1) == '' ? blist.pop() : null; // remove the last element if empty

    for (var i = 0, len = alist.length; i < len;i++){
        if (alist[i] != blist[i]){ // find the first non-equal part
           if (alist[i].match(/\d/)) // if numeric
           {
              return +alist[i] - +blist[i]; // compare as number
           } else {
              return alist[i].localeCompare(blist[i]); // compare as string
           }
        }
    }

    return true;
}

Syntax

var data = ["a1b3","a10b11","b10b2","a9b2","a1b20","a1c4"];
data.sort( compareLists );
alert(data);

demo at http://jsfiddle.net/h9Rqr/7/


Solution 5:

Here's a more complete solution that sorts according to both letters and numbers in the strings

function sort(list) {
    var i, l, mi, ml, x;
    // copy the original array
    list = list.slice(0);

    // split the strings, converting numeric (integer) parts to integers
    // and leaving letters as strings
    for( i = 0, l = list.length; i < l; i++ ) {
        list[i] = list[i].match(/(\d+|[a-z]+)/g);
        for( mi = 0, ml = list[i].length; mi < ml ; mi++ ) {
            x = parseInt(list[i][mi], 10);
            list[i][mi] = !!x || x === 0 ? x : list[i][mi];
        }
    }

    // sort deeply, without comparing integers as strings
    list = list.sort(function(a, b) {
        var i = 0, l = a.length, res = 0;
        while( res === 0 && i < l) {
            if( a[i] !== b[i] ) {
                res = a[i] < b[i] ? -1 : 1;
                break;
            }

            // If you want to ignore the letters, and only sort by numbers
            // use this instead:
            // 
            // if( typeof a[i] === "number" && a[i] !== b[i] ) {
            //     res = a[i] < b[i] ? -1 : 1;
            //     break;
            // }

            i++;
        }
        return res;
    });

    // glue it together again
    for( i = 0, l = list.length; i < l; i++ ) {
        list[i] = list[i].join("");
    }
    return list;
}

Post a Comment for "How To Sort Strings In Javascript Numerically"