www.webdeveloper.com
Results 1 to 8 of 8

Thread: Need help sorting a date/time array.

  1. #1
    Join Date
    Aug 2009
    Posts
    14

    Need help sorting a date/time array.

    I'm needing some help to sort my data array by a timestamp field .....

    I have a 2D array "AvatarArr" populated with data from a remote source, but it is basically "Name1, Login Timestamp1, Logout Timestamp1, Location1,Name2, Login Timestamp2.....etc"

    I also have the following sort functions defined..
    Code:
    function byName (a, b) {return a[0] == b[0] ? 0 : a[0] < b[0] ? -1 : 1}
    function byLogin (a, b) {return a[1] == b[1] ? 0 : a[1] < b[1] ? -1 : 1}
    function byLogout (a, b) {return a[2] == b[2] ? 0 : a[2] < b[2] ? -1 : 1}
    function byLocation (a, b) {return a[3] == b[3] ? 0 : a[3] < b[3] ? -1 : 1}
    So when I populate my table with data I can sort the table by any column, for example to sort by name I call
    Code:
    AvatarArr.sort(byName);
    Now this works EXCEPT my Timestamp data isn't in a format that makes it easy to sort.


    The timestamp comes in as
    Mon 10/26/2009 at 2:05 am
    for example.

    Is there a trick or some way of changing the function definition of byLogin to handle sorting a timestamp like this correctly (by date/time) rather than what currently happens which is alphabetically?

    Thanks
    Richard

  2. #2
    Join Date
    Feb 2006
    Posts
    2,927
    if you remove the 'at', you can get an integer timestamp from the string with Date.parse(string)-

    Code:
    return Date.parse(a[1].replace('at',''))-Date.parse(b[1].replace('at',''))
    // test
    Code:
    var A= [
        ['jane ','Mon 10/19/2009 at 2:06 am'],
        ['sam ','Tue 10/27/2009 at 2:05 am'], 
        ['bob ','Mon 10/26/2009 at 2:05 am'], 
        ['ann ','Mon 10/19/2009 at 2:05 am']
    ];
    
    A.sort(function(a, b){
        return Date.parse(a[1].replace('at ',''))- Date.parse(b[1].replace('at ',' '))
    });
    A.join('\n')

    returned value:
    ann ,Mon 10/19/2009 at 2:05 am
    jane ,Mon 10/19/2009 at 2:06 am
    bob ,Mon 10/26/2009 at 2:05 am
    sam ,Tue 10/27/2009 at 2:05 am

  3. #3
    Join Date
    Aug 2009
    Posts
    14
    Thanks for the quick reply mrhoo,

    This seems to be working as you suggest, the only issue I have now is that if somebody IS currently online the Logout timestamp is just "1" instrad of a valid timestamp.

    This mucks up the sorting, what I need to do is have all the "1"'s displayed first if sorted by Logout(those currently oline displayed first) ... maybe if they were "0" instead of "1", would the Date.parse() then work and generate a valid date that would be sorted?

    Cheers
    Richard
    Last edited by rpalmer68; 10-26-2009 at 05:00 PM.

  4. #4
    Join Date
    Feb 2006
    Posts
    2,927
    I'd look at the input and handle 1's differently.
    Date.parse('1') returns NaN,

    //
    Code:
    var A= [
    ['jane ','Mon 10/19/2009 at 2:06 am'],
    ['sam ','Tue 10/27/2009 at 2:05 am'],
    ['jim ','1'],
    ['bob ','Mon 10/26/2009 at 2:05 am'],
    ['ann ','Mon 10/19/2009 at 2:05 am'],
    ['stan','1']
    ];
    A.sort(function(a, b){
        a= Date.parse(a[1].replace('at ',''));
        b= Date.parse(b[1].replace('at ',''));
        if(isNaN(a) || isNaN(b)){
            return (isNaN(a))? -1: 1;
        }
        return a-b;
    });
    
    alert(A.join('\n'))
    // returned value:
    jim ,1
    stan,1
    ann ,Mon 10/19/2009 at 2:05 am
    jane ,Mon 10/19/2009 at 2:06 am
    bob ,Mon 10/26/2009 at 2:05 am
    sam ,Tue 10/27/2009 at 2:05 am
    Last edited by mrhoo; 10-26-2009 at 05:51 PM. Reason: format

  5. #5
    Join Date
    Aug 2009
    Posts
    14
    Excellent, thanks for that mrhoo.


    I have check boxes for what I want to sort by, so I can in fact sort by Name AND Logout.

    So this means I could have both of these run.

    Code:
    if (form1.byname.checked) AvatarArr.sort(byName);
    if (form1.bylogout.checked) AvatarArr.sort(byLogout);
    So this would sort the array by name, and then sort it by the Logout timestamp.

    Your suggested code is working if I sort by Name and Logout, but now when I get the table populated I have the users with logout="1" at the top YAY!, BUT they are in reversed order (Z - A) rather than what I need which is A-Z.


    So for anybody else reading this and trying to do somethig similar... I changed
    Code:
    return (isNaN(a))? -1: 1;
    to
    Code:
    return isNaN(a)&& isNaN(b)? 0 :(isNaN(a))? -1 : 1;
    making the full function..
    Code:
    function byLogout(a, b){
       a= Date.parse(a[2].replace('at ',''));
       b= Date.parse(b[2].replace('at ',''));
          if(isNaN(a) || isNaN(b)){
             return isNaN(a)&& isNaN(b)? 0 :(isNaN(a))? -1 : 1;
           }
        return a - b ;
    };


    Cheers
    Richard

  6. #6
    Join Date
    Aug 2009
    Posts
    14
    hmm, the above solution has been working perfectly for the last few days, but today I have a problem.

    I have logout dates of "Sat 10/31/2009 at 12:36 am" in amongst my logged in users.

    I can only assume date.parse is returning NaN for this date for some reason... could this be possible?

    Richard

  7. #7
    Join Date
    Feb 2006
    Posts
    2,927
    You are removing the 'at 's, including the 'at ' in 'Sat '-
    replace ' at' instead, to only remove at if preceded by a space.

  8. #8
    Join Date
    Aug 2009
    Posts
    14
    Duh! Of course... I knew it was going to be something simple!

    Thanks a lot mrhoo.

    Richard

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

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



Recent Articles