Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I would create a new class called <code>ItemGroup</code>, and then add an extra ivar called <code>group</code> to your item class:</p> <pre><code>@interface ItemGroup : NSObject { NSNumber * time; } @property (nonatomic, copy) time; @end @interface ItemClass : NSobject { NSString * name; NSNumber * time; ItemGroup * group; } @property (nonatomic, copy) NSString * name; @property (nonatomic, copy) NSNumber * time; @property (nonatomic, assign) ItemClass * group; // note: must be assign @end </code></pre> <p>Then, you could do the following:</p> <pre><code>NSMutableDictionary * groups = [NSMutableDictionary dictionaryWithCapacity:0]; for (ItemClass * item in sourceData) { ItemGroup * group = [groups objectForKey:item.name]; if (group == nil) { group = [[ItemGroup alloc] init]; [groups setObject:group forKey:item.name]; [group release]; group.time = item.time; } else if (item.time &lt; group.time) { group.time = item.time; } item.group = group; } </code></pre> <p>This code loops through the unsorted array, keeping track of the minimum time for each group, and also <em>setting</em> the group for each item. With that complete, you simply sort on <code>group.time</code> and <code>time</code>:</p> <pre><code>NSSortDescriptor * groupSorter; groupSort = [NSSortDescriptor sortDescriptorWithKey:@"group.time" ascending:YES]; NSSortDescriptor * timeSorter; timeSort = [NSSortDescriptor sortDescriptorWithKey:@"time" ascending:YES]; NSArray * sortDescriptors = [NSArray arrayWithObjects:groupSort, timeSort, nil]; NSArray * sorted = [sourceData sortedArrayUsingDescriptors:sortDescriptors]; </code></pre> <p>And that should do the trick!</p> <p><strong><em>UPDATE</em></strong>: Note that you could get <em>much</em> better performance if you were able to assign the groups straight out of the gate. Something like this:</p> <pre><code>@interface ItemGroup : NSObject { NSString * name; NSNumber * time; } @property (nonatomic, copy) NSString * name; @property (nonatomic, copy) NSSNumber * time; @end @interface ItemClass : NSObject { ItemGroup * group; NSNumber * time; } @property (nonatomic, retain) ItemGroup * group; @property (nonatomic, copy) NSNumber * time; @end </code></pre> <p>Now, if you maintain a list of groups somewhere (they could even go in an array somewhere, if need be):</p> <pre><code>ItemGroup * group_A = [[ItemGroup alloc] init]; group_A.name = @"A"; ItemGroup * group_B = [[ItemGroup alloc] init]; group_B.name = @"B"; ... </code></pre> <p>And instead of setting the <em>names</em> of your data items, you set their group:</p> <pre><code>someItem.group = group_A; someItem.time = GetSomeRandomTimeValue(); [sourceData addObject:someItem]; .... </code></pre> <p>This would greatly simplify the loop used to set group times:</p> <pre><code>for (ItemClass * item in sourceData) { if (item.time &lt; group.time) { group.time = item.time; } } </code></pre> <p>And, if you really wanted to be <em>blazing</em> fast about it, you could even modify the property setter for your <code>time</code> property to set the group times on the fly:</p> <pre><code>@implementation ItemClass - (void)setTime:(NSNumber *)newTime { if (newTime &lt; group.time) { group.time = newTime; } time = [newTime copy]; } @end </code></pre> <p>Note that you would have to be sure that <code>group</code> had been set before you set the time. With this in place, you wouldn't need that sorting loop at all. The sortDescriptors would be enough.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload