4

I am befuddled by this. I've done plenty of sorting in Js, but for some reason I'm getting strange behavior.

x = [{ts: "2013-09-24 14:44:22"}, {ts: "2013-09-24 14:08:26"}, {ts: "2013-09-24 17:37:42"}].sort(function(a,b) {return a.ts < b.ts;});
console.log(x); // this is sorted

But, when I use a longer array, the sort doesn't work. Just look at the first three objects of the second sort:

http://jsfiddle.net/HWx7p/

Any ideas?

4
  • Um... sort modifies the original array and returns a boolean... Commented Sep 25, 2013 at 14:04
  • It looks sorted to me. Commented Sep 25, 2013 at 14:04
  • Do this: .sort(function(a,b) { return b.ts.localeCompare(a.ts); }); Commented Sep 25, 2013 at 14:07
  • @Kolink: .sort() returns the original Array. Commented Sep 25, 2013 at 14:08

5 Answers 5

3

Your comparator needs to return a number, not a boolean.

A negative number if less than, 0 if equal, a positive number if greater than.

.sort(function(a,b) {
    if(a.ts == b.ts) return 0;
    return a.ts < b.ts ? -1 : 1;
});

http://jsfiddle.net/HWx7p/8/

Sign up to request clarification or add additional context in comments.

Comments

3

Try changing your sort function:

.sort(function(a,b) {

    if(a.ts < b.ts) return -1;
    else if(a.ts > b.ts) return 1;
    return 0;

});

Demo: http://jsfiddle.net/maniator/HWx7p/6/

Comments

1

Sort it as dates, that is what you want :

y.sort(function(a,b) { 
   return new Date(a.ts) < new Date(b.ts);
});

forked fiddle http://jsfiddle.net/bHh4g/


Has accidently removed console.log(y); in the fiddle, but reinserted it will show it now sorts correct.


Finally

It turns out FireFox / Safari Date() doesnt like dates on the form "2013-09-24 14:44:22" they need y/m/d instead :

y.sort(function(a,b) { 
    var d1 = a.ts.replace(/-/g,'/');
    var d2 = b.ts.replace(/-/g,'/');
    d1 = new Date(d1);
    d2 = new Date(d2);
    return (d1 < d2) ? -1 : (d1 > d2) ? 1 : 0;
});

console.log(y);

forked fiddle http://jsfiddle.net/Jnx4w/
works in both Chrome / FF.

1 Comment

So I tested it again and as before, it doesn't sort correctly, at least in Safari, see. I wonder also, which overhead this produces over a simple string comparison.
0

Two things: your sort function should return a signed number, not a boolean, and it looks like you want to compare dates, not strings.

For your sort function, try:

function(a,b){ return (new Date(a)).getTime() - (new Date(b)).getTime();}

Comments

-2

You compare string... no timestamp ;)

y = y.sort(function(a,b) {
    var ta = (+new Date(a.ts));
    var tb = (+new Date(b.ts));
    if (ta < tb)
        return -1;
    if (ta > tb)
        return 1;
    return 0;
});

Here: http://jsfiddle.net/HWx7p/

1 Comment

I don't know what you mean by cross-compatible, but have a look at the strings. That is a string sortable date format. If you sort those strings as string they will sort in date order. Always.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.