0

I populate a NSMUtableArray list of items in a UITableView .

I was wondering if there is a function that I can use to invert order of the displayed list ?

I know that I can probably just create a new list with an inverted for loop but that s somehow a waste of memory

Thank you

user1051935
  • 579
  • 1
  • 10
  • 29

3 Answers3

3

Why not just invert the order you fetch the data inside the datasource method?

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
  NSUInteger dataItemIndex = self.inverted ? (self.dataItems.count - 1 - indexPath.row) : indexPath.row;

  // Fetch item at index and return cell ...
}

I'm afraid there is no built in method to invert the object order of an array. This question may also be of help.

Community
  • 1
  • 1
1

You could check out:

NSSortDescriptor

From the docs: An instance of NSSortDescriptor describes a basis for ordering objects by specifying the property to use to compare the objects, the method to use to compare the properties, and whether the comparison should be ascending or descending.

To specify how the elements in a table view should be arranged (see sortDescriptors)

Though if it is just a simple flipping ascending to descending I'd probably just do this:

- (NSMutableArray *)reverseArrayOrder {
    NSMutableArray *reversedArray = [NSMutableArray arrayWithCapacity:[self count]];
    NSEnumerator *enumerator = [self reverseObjectEnumerator];
    for (id element in enumerator) {
        [reversedArray addObject:element];
    }
    return reversedArray;
}
Glorfindel
  • 21,988
  • 13
  • 81
  • 109
PruitIgoe
  • 6,166
  • 16
  • 70
  • 137
0

Add this in a category to NSMutableArray:

- (void) invertArray{
    NSUInteger operationCount = self.count / 2;
    NSUInteger lastIndex = self.count - 1;
    id tmpObject;
    for (int i = 0; i < operationCount; i++){
        tmpObject = [self objectAtIndex:i];
        [self replaceObjectAtIndex:i withObject:[self objectAtIndex:lastIndex - i]];
        [self replaceObjectAtIndex:lastIndex - i withObject:tmpObject];
    }
}

This will invert the array without creating any new array. Moreover, it's fairly efficient, needing only to iterate over half the array.

If you need to arrange the tableView while you rearrange the array, use this method (again as a category to NSMutableArray):

- (void) invertArrayWithOperationBlock:(void(^)(id object, NSUInteger from, NSUInteger to))block{
    NSUInteger operationCount = self.count / 2;
    NSUInteger lastIndex = self.count - 1;
    id tmpObject1;
    id tmpObject2;
    for (int i = 0; i < operationCount; i++){
        tmpObject1 = [self objectAtIndex:i];
        tmpObject2 = [self objectAtIndex:lastIndex - i];
        [self replaceObjectAtIndex:i withObject:tmpObject2];
        [self replaceObjectAtIndex:lastIndex - i withObject:tmpObject1];
        if (block){
            block(tmpObject1, i, lastIndex - i);
            block(tmpObject2, lastIndex - i, i);
        }
    }
}

This will allow you to pass a block to the method to execute code for each move. You can use this to animate the rows in your table view. For example:

[self.tableView beginUpdates];
[array invertArrayWithOperationBlock:^(id object, NSUInteger from, NSUInteger to){
    [self.tableView moveRowAtIndexPath:[NSIndexPath indexPathForRow:from inSection:0] toIndexPath:[NSIndexPath indexPathForRow:to inSection:0];
}];
[self.tableView endUpdates];
Aaron Hayman
  • 8,492
  • 2
  • 36
  • 63