Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript sort function nor working in Safari/iPhone

I've looked through most of the previous asked questions about this topic, but still can't get mine to work.

I have this code, which sorts an array of objects:

array.sort(function(a,b){
  var dateA=new Date(a.created_time), dateB=new Date(b.created_time)
  return (dateB > dateA) ? 1 : (dateB < dateA) ? -1 : 0;
});

It works fine in FF and Chrome (desktop), but fails in Safari(desktop/iphone) and Chrome(iphone)

The array of objects is an AJAX call from Facebook, getting a wall feed, and I want to sort by created_time.

Thanks in advance...

like image 665
afcdesign Avatar asked Jun 03 '13 08:06

afcdesign


1 Answers

The problem is that Safari and the other mentioned Browser's (chrome on iphone) can't parse the input String you pass to the constructor. Which results in an Invalid Date which primitives value is NaN

Hence, the sort function does not work as inteded, comparing return (NaN > NaN) ? 1 : (NaN < NaN) ? -1 : 0;, resulting in return 0

To work around this, with a minimum of parsing effort, i thought of just splitting the String by -|:|T|\+. And use The date parts on their own to construc a new Date

Note: Unfortunetaly sth like var d = Date.apply([year,month,...]) is not possible

So here is a sort function which works for me on Safari

var dates = [{
        name: "A",
        created_time: '2013-06-05T08:05:06+0000'
    }, {
        name: "B",
        created_time: '2013-06-03T10:05:06+0000'
    }, {
        name: "C",
        created_time: '2013-06-03T01:05:06+0000'
    }
];

var sorted = dates.sort(function (a, b) {
        var reg = /-|:|T|\+/; //The regex on which matches the string should be split (any used delimiter) -> could also be written like /[.:T\+]/
        var parsed = [ //an array which holds the date parts for a and b
            a.created_time.split(reg), //Split the datestring by the regex to get an array like [Year,Month,Day,Hour,...]
            b.created_time.split(reg)
        ];
        var dates = [ //Create an array of dates for a and b
            new Date(parsed[0][0], parsed[0][1], parsed[0][2], parsed[0][3], parsed[0][4], parsed[0][5]),//Constructs an date of the above parsed parts (Year,Month...
            new Date(parsed[1][0], parsed[1][1], parsed[1][2], parsed[1][3], parsed[1][4], parsed[1][5])
        ];
        return dates[0] - dates[1]; //Returns the difference between the date (if b > a then a - b < 0)
    });

Which gives the output:

console.log(sorted);
/*
[{
        "created_time": "2013-06-03T01:05:06+0000",
        "name": "C"
    }, {
        "created_time": "2013-06-03T10:05:06+0000",
        "name": "B"
    }, {
        "created_time": "2013-06-05T08:05:06+0000",
        "name": "A"
    }
]
*/

Demo on JSBin

like image 94
Moritz Roessler Avatar answered Sep 22 '22 19:09

Moritz Roessler