views:

32

answers:

4

Hi guys,

I'm trying to sort an Array of dates from latest to oldest, and unfortunately list.sort (by default) only sorts the first number. My array looks like this:

var MyArray = ["13 Jun", "09 Jun", "25 Aug", "30 Jun", "13 Aug"];

I tried to make a function for the .sort to reference, but the whole process is somewhat confusing to me. Could anyone help me out?

A: 

You can pass a function to sort to do custom sorting:

function sortDate (a,b) {
    var aa = a.split(' ');
    var bb = b.split(' ');
    var months = {
        Jan : 1,
        Feb : 2,
        Mar : 3 /* you do the rest ... */
    }

    if (months[a[1]] > months[b[1]]) return 1;
    if (months[a[1]] < months[b[1]]) return -1;

    return parseInt(a[0],10) - parseInt(b[0],10);
}

MyArray.sort(sortDate);
slebetman
A: 

You would have to pass a sorting function to the sort method and define a date parsing function that creates an ordered representation of the date like so:

var MyArray = ["13 Jun", "09 Jun", "25 Aug", "30 Jun", "13 Aug"];
MyArray.sort(function (a, b) {
    a = parseDate(a);
    b = parseDate(b);
    if (a < b) {
            return 1;
    } else if (a > b) {
            return -1;
    } else {
            return 0;
    }
});
Jonas Klemming
+3  A: 

You'll have to parse the strings into Date() objects, which would be straightforward enough if it weren't for IE's poor implementation of date string parsing. Fortunately, you can use setDate() and setMonth() with consistency across browsers, both accept numbers - 1-31 for setDate(), 0-11 for setMonth(). Setting up an object map for the month names will help.

This works for me:

(function () { 
    // Set up our variables, 2 date objects and a map of month names/numbers
    var ad = new Date(),
        bd = new Date(),
        months = {
            Jan: 0, Feb: 1, Mar: 2, Apr: 3, May: 4, Jun: 5,
            Jul: 6, Aug: 7, Sep: 8, Oct: 9, Nov:10, Dec:12
        };

    MyArray.sort(function (a,b) {
        // Split the text into [ date, month ]
        var as = a.split(' '),
            bs = b.split(' ');

        // Set the Date() objects to the dates of the items
        ad.setDate(as[0]);
        ad.setMonth(months[as[1]]);
        bd.setDate(bs[0]);
        bd.setMonth(months[bs[1]]);

        /* A math operation converts a Date object to a number, so 
           it's enough to just return date1 - date2 */
        return ad - bd;
    });
})();
//-> ["09 Jun", "13 Jun", "30 Jun", "13 Aug", "25 Aug"]

I've set up an example for you - http://jsfiddle.net/Tw6xt/

Andy E
This works wonderfully! Thank you
Jon McIntosh
A: 

Here's a solution that doesn't reply on any constants.

var MyArray = ["13 Jun", "09 Jun", "25 Aug", "30 Jun", "13 Aug"];
var DateArray = [];
var SortedArray = [];
var dateBits;
for (var index = 0; index < MyArray.length; index++) {
 DateArray.push(new Date(MyArray[index] + " 2000"));
}
SortedArray = DateArray.sort();
MyArray = [];
for (var index = 0; index < SortedArray.length; index++) {
  dateBits = SortedArray[0].toDateString().substr(4, 6).split(" ");
  MyArray[index] = dateBits[1] + " " + dateBits[0];
}
Paul Schreiber