views:

302

answers:

3

Hi all, I have an Array called alarmQueue. I'm pushing a new arrays in to it with the contents [hours:int, minutes:int, seconds:int] and I'd like to use alarmQueue.sortOn() to sort the queue of alarms Ascending but I'm having problems getting my head around the logic.

// the function to push the alarm in to a queue
public function setAlarm(_hours:int = 0, _minutes:int = 0, _seconds:int = 0):void
{
    var alarmAsArray:Array = new Array(_hours, _minutes, _seconds);
    alarmQueue.push(alarmAsArray);

    alarmQueue.sortOn([0, [1, 2]], Array.NUMERIC | Array.DESCENDING);
    trace(alarmQueue);
}

I'm setting these alarms:

clock.setAlarm(1, 0, 31);  // alarm 1
clock.setAlarm(12, 1, 21); // alarm 2
clock.setAlarm(12, 1, 19); // alarm 3

and getting the following traces:

1,0,31
12,1,21,1,0,31
12,1,21,12,1,19,1,0,31

I seem to be ordering them as: alarm 2, alarm 3, alarm 1 but I want to be ordering them by hour, then minute and seconds.

Can anyone shed any light on my sorting woes? Cheers!

+1  A: 

This should work, but I have not tested it.

public function setAlarm(_hours:int = 0, _minutes:int = 0, _seconds:int = 0):void
{    
  alarmQueue.push(
  {
    hours: _hours,
    minutes: _minutes,
    seconds: _seconds
  });

  alarmQueue.sortOn(['hours', 'minutes', 'seconds'], Array.NUMERIC);
}
Lior Cohen
why is second parameter enclosed in square brackets?
Amarghosh
To specify that you would like to apply Array.NUMERIC and Array.ASCENDING to each and every one of the fieldnames?
Lior Cohen
Have you tested this? Because livedocs doesn't say anything about being able to pass different sort options for different fields http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/Array.html#sortOn()
Amarghosh
I believe `Array.NUMERIC | Array.ASCENDING` would be enough
Amarghosh
From livedocs: Note: The fieldName and options arrays must have the same number of elements; otherwise, the options array is ignored. Also, the Array.UNIQUESORT and Array.RETURNINDEXEDARRAY options can be used only as the first element in the array; otherwise, they are ignored.
Lior Cohen
And since I don't have access to a Flex compiler atm, I can't test whether a single Array.NUMERIC | Array.ASCENDING would work. If you can test and verify this then I would alter the answer to reflect your findings.
Lior Cohen
I've modified the answer above to follow the comments above. Also, it seems like Array.ASCENDING doesn't actually exist as an option since it is the default behavior. Anton, the code above should work as expected, post modification.
Lior Cohen
How could I miss that - it was very much there in the same paragraph. Thanks for pointing out them :)
Amarghosh
A: 

Hi all, thanks for the feedback.

I've tested:

alarmQueue.push(
      {
       hours: _hours,
       minutes: _minutes,
       seconds: _seconds
      });

      alarmQueue.sortOn(
       ['hours', 'minutes', 'seconds'],
       [Array.NUMERIC | Array.ASCENDING, Array.NUMERIC | Array.ASCENDING, Array.NUMERIC | Array.ASCENDING]
      );

      if(alarmQueue.length == 3)
      {
       for(var i:int = 0; i SMALLERTHAN alarmQueue.length; i++)
       {
        trace(alarmQueue[i].hours,alarmQueue[i].minutes, alarmQueue[i].seconds);
       }
      }

I had to change the trace slightly due to the array items being objects now and used SMALLERTHAN as the < symbol seems to break to code tags here, but the app wouldn't compile as Flex Builder was telling me Array.ASCENDING not being a sort method, so I checked livedocs and found no mention of it there too. Any other guesses?

anton
You should edit your existing question with updates instead of providing updates in an answer - answer order is set by votes so your update doesn't always appear in the same place this way.
Reuben
A: 

Found the answer after some tinkering. The default method of sorting is ascending but there's no option to set Ascending as a secondry sorting method. So by performing two sorts, the first descending on the minutes and seconds, the second is a sortOn the hours with no parameter applied so it sorts ascending!

var alarmAsArray:Array = new Array(_hours, _minutes, _seconds);
         alarmQueue.push(alarmAsArray);

         alarmQueue.sortOn([1, 2]);
         alarmQueue.sortOn([0], Array.DESCENDING);

         if(alarmQueue.length == 3)
         {
          trace(alarmQueue);
         }

this gives the correct output of: 12,1,19 12,1,21 1,0,31

Many thanks all! ant

anton