2

I'd like to sort by time,day. Here is my attempt:

var days = new Array();
var days['SU'] = 0;
var days['MO'] = 1;
var days['TU'] = 2;
var days['WE'] = 3;
var days['TH'] = 4;
var days['FR'] = 5;
var days['SA'] = 6;

events.sort(function(a, b)
{
    if(a['day'] != b['day'])
    {
        return (days[a['day']] < days[b['day']]) ? 1 : -1;
    }
    else if(a['time'] != b['time'])
    {
        return (a['time'] < a['time']) ? 1 : -1;
    }
    else
        return 0;
);

It's not tested, but am I doing it correct? (Time asc, days asc) Mon 8am, Tues 8am, Mon 9pm is the order I'm looking for.

Cheers.

events[0]['day'] = 'MO';
events[0]['time'] = 8;
events[1]['day'] = 'MO';
events[1]['time'] = 21;
events[2]['day'] = 'TU';
events[2]['time'] = 8;

My solution which seems to work thanks to @T.J. Crowder

events = new Array();
events[0] = new Array();
events[0]['day'] = 'MO';
events[0]['time'] = 8;
events[1] = new Array();
events[1]['day'] = 'MO';
events[1]['time'] = 21;
events[2] = new Array();
events[2]['day'] = 'TU';
events[2]['time'] = 8;

var days = {
    'SU': 0,
    'MO': 1,
    'TU': 2,
    'WE': 3,
    'TH': 4,
    'FR': 5,
    'SA': 6
};

events.sort(function(a, b)
{
    if (a.time != b.time)
    {
        return a.time - b.time;
    }
    else if (a.day != b.day)
    {
        return days[a.day] - days[b.day];
    }
    else
    {
        return 0;
    }
});

Condensed:

events.sort(function(a, b)
{
    return a.time != b.time
       ? a.time - b.time
       : days[a.day] - days[b.day];
});
5
  • 3
    Try posting the data you are sorting, the attempt at sorting and the sorting result. From your post I gather you wrote some code and came here asking us if it arbitrarily works. Commented Apr 10, 2011 at 5:42
  • To add to @Khez: why not simply test it, and then ask here if you actually have a problem? Commented Apr 10, 2011 at 5:43
  • Well first and foremost, you should be using an Object and not an Array - JavaScript arrays are not associated arrays, while objects can be used as hashmaps Commented Apr 10, 2011 at 5:45
  • @Yi Jiang: Agreed he should be using Object rather than Array, but JavaScript arrays are associative arrays. JavaScript arrays are everything JavaScript objects are, plus some special handling around numeric property keys and a length property. So his code using Array will work. But since it doesn't take advantage of any of the Array-ness, there's no reason to use Array. Commented Apr 10, 2011 at 5:55
  • If you want to post an answer your own question, that's perfectly fine, but post it as an answer. It makes it very hard to read the question when there's an answer intermixed with it. More: stackoverflow.com/faq Separately, see the live example in my answer for how you can initialize events much more clearly and efficiently. Commented Apr 10, 2011 at 6:10

1 Answer 1

5

Your fundamental approach is sound. A few notes:

  1. You're not using days as an array, so I wouldn't make it an array. Instead:

    var days = {
        'SU': 0,
        'MO': 1,
        'TU': 2,
        'WE': 3,
        'TH': 4,
        'FR': 5,
        'SA': 6
    };
    

    Also, you don't need those quotes since none of those strings is a keyword, so:

    var days = {
        SU: 0,
        MO: 1,
        TU: 2,
        WE: 3,
        TH: 4,
        FR: 5,
        SA: 6
    };
    

    ...but you may choose to keep them as a style thing, or to defend against adding ones that are keywords later.

  2. You don't have to use the bracketed notation to look up a property (a['day']) unless the string you're using for the property name is dynamic or the property name is a reserved word. day is neither, so you can use the simpler dotted notation (a.day).

  3. There is no elseif in JavaScript; use else if.

  4. You can simplify this:

    return (days[a['day']] < days[b['day']]) ? 1 : -1;
    

    to

    return days[a.day] - days[b.day];
    

    ..and you may be able to do something similar with your time values, but I don't know what they are, so... now that you've posted them, I do, and you can.

  5. Strongly recommend always using braces, not just when you "need" them. (None of your three branches actually needs them, but you're only using them on two.)

  6. You've compared a['time'] to a['time] rather than b['time'] when checking for equality.

  7. You haven't ended your function (missing })

  8. Since you can just subtract your time values, you don't need your final equality check.

    So:

    events.sort(function(a, b)
    {
        if (a.day != b.day)
        {
            return days[a.day] - days[b.day];
        }
        else
        {
            return a.time - b.time;
        }
    });
    

    ...or you can condense it further:

    events.sort(function(a, b)
    {
        return (a.day != b.day
               ? days[a.day] - days[b.day]
               : a.time - b.time);
    });
    

Live example

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

5 Comments

Thanks for your help, how does the - (minus) work? is b - a ascending? It works just doesn't sort correctly.
@Steven: If a is TU/8 and b is TU/6, a.day == b.day and then we return b.time - a.time, which is -2, which means that b should be before a. And similarly when we compare days[a.day] to days[b.day]. It should be sorting correctly if I'm understanding your data.
Thanks for your help, I've put my solution at the top. How would I condense it?
@Steven: I seem to have had my a's and b's reversed. Edited, with example.
@T.J.Crowder Personally, I don't see it as a stylistic change - the list is now actually a list, instead of a bunch of p tags starting with 1), 2)..., which is better markup.

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.