Results 1 to 4 of 4

Thread: Sorting mixed values

  1. #1
    Join Date
    Apr 2007
    Posts
    31
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Sorting mixed values

    Hi,
    Is there a way to sort mixed values (e.g. 2a, 2c, 2b, 3c, 1c, 5a).
    I need to sort them by number then by letter (e.g 1c, 2a,2b,2c,3c,5a). There are only w letters, a,b,c and w on its own(no number in front).

    The sorting script I have will only sort by integers or by strings.

    example of part of the script- Maybe I need to change the letters to a numeric value? so w becomes 0, 2a becomes 21 and 2b becomes 22 and 3c becomes 31 and then allowing this bit to sort it.

    Any suggestions?

    // If the item matches a numeric pattern
    if (itm.match(/(\d*,\d*$)|(^-?\d\d*\.\d*$)|(^-?\d\d*$)|(^-?\.\d\d*$)/)) {
    // Replace anything that is not part of a number (decimal pt, neg sign, or 0 through 9) with an empty string.
    sortValue = itm.replace(/[^0-9.-]/g,'');
    // sortValue = sortValue.replace(/,/g,'');
    if (isNaN(sortValue)) {
    sortValue = 0;
    } else {
    sortValue = parseFloat(sortValue);
    }
    }

  2. #2
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    I came up with this demo, I put letters only at the end, but they could go at the beginning (just get rid of the highlighted lines):

    Code:
    <script type="text/javascript">
    Array.prototype.numlet = function(){
    var t = [], r = [], o = {};
    var n = function(item){return isNaN(parseInt(item))? 0 : parseInt(item);};
    var c = function(item){return typeof item == 'string' && item.length==2? n(item.charAt(0)) : 0;};
    for (var i = this.length - 1; i > -1; --i)
    if(!o[c(this[i])])
    o[c(this[i])] = [this[i]];
    else o[c(this[i])][o[c(this[i])].length] = this[i];
    for (var p in o){
    t[t.length] = p;
    o[p].sort();
    }
    t.sort();
    for(var i = 0; i < t.length; ++i)
    if(t[i] - 0)
    r = r.concat(o[t[i]]);
    if(t[0] == 0)
    r = r.concat(o[0]);
    for (var i = this.length - 1; i > -1; --i)
    this[i] = r[i];
    }
    var x = ['2c','b','4z','3y','w','3c','4t','2a','9a', '3q'];
    x.numlet();
    alert(x);
    </script>
    The code is a little more complex than it has to be, as long as the items in your array to be sorted like this are in the exact format you describe. If for example one of them were to be a raw number, it would be treated as a single letter. It can get a little confusing, because 2c ,3a, etc. are technically numbers in certain cases (hex), but '2c', and '3a' are strings.

    Also, the code could possibly be simplified, even while retaining this primitive error checking.
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  3. #3
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    Yeah, I was right, here is a bit simpler method (requires IE 5.5 or better - or just about any other browser):

    Code:
    <script type="text/javascript">
    Array.prototype.numlet = function(){
    var t = [], r = [], o = {}, i, p,
    c = function(item){return isNaN(parseInt(item.toString(10)))? 9999999 : parseInt(item);};
    
    for (i = this.length - 1; i > -1; --i)
    if(o[c(this[i])]) o[c(this[i])].push(this[i]);
    else o[c(this[i])] = [this[i]];
    
    for (p in o) t.push(p), o[p].sort();
    
    t.sort(function(a, b){return b - a;});
    
    for (i = t.length - 1; i > -1; --i)
    r = r.concat(o[t[i]]);
    
    for (i = this.length - 1; i > -1; --i)
    this[i] = r[i];
    };
    var x = ['2c','b','4z','3y','w','3c','4t','2a','9a', '3q'];
    x.numlet();
    alert(x);
    </script>
    It avoids the issue with numbers vs strings by making everything a string, and will work with arrays having entries like:

    974gthw

    and:

    black

    as well as with the typical sort of entries you mentioned.

    To get the letter entries to come first in this version, just change the highlighted 9999999 to 0.
    Last edited by jscheuer1; 07-02-2008 at 06:44 PM. Reason: simplify code further - add comment
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  4. #4
    Join Date
    Apr 2007
    Posts
    31
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    Thanks for the help, it gives a good start for what I am trying to do.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •