17

I'm getting the select items from a table view with:

NSIndexSet *selectedItems = [aTableView selectedRowIndexes];

what's the best way to get the indexes in a NSArray object?

Abizern
  • 129,329
  • 36
  • 198
  • 252
Mr_Nizzle
  • 6,324
  • 11
  • 52
  • 85
  • i have a method getting an NSArray as parameter to delete multiple records selected from the tableview – Mr_Nizzle Sep 22 '10 at 20:11
  • 6
    That seems a little bit circular. If the purpose of the array is to contain a set of indexes, why not have the method take an NSIndexSet instead? – Chuck Sep 22 '10 at 20:16
  • is there not a method on NSArray which returns the elements in provided NSIndexSex? – alfwatt Sep 20 '17 at 06:00

5 Answers5

24

Enumerate the set, make NSNumbers out of the indexes, add the NSNumbers to an array.

That's how you'd do it. I'm not sure I see the point in transforming a set of indexes into a less efficient representation, though.

To enumerate a set, you have two options. If you're targeting OS X 10.6 or iOS 4, you can use enumerateIndexesUsingBlock:. If you're targeting earlier versions, you'll have to get the firstIndex and then keep asking for indexGreaterThanIndex: on the previous result until you get NSNotFound.

Chuck
  • 222,660
  • 29
  • 289
  • 383
  • you're right it's just that i don't know how to get the indexes from the NSIndexSet with a while loop or a foreach loop.... – Mr_Nizzle Sep 22 '10 at 20:22
  • 5
    It's in the docs: http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Collections/Articles/index.html%23//apple_ref/doc/uid/TP40010165-SW4 – Wevah Sep 22 '10 at 20:43
  • @Chuck one reason to do so would be to allow the persistance of the NSIndexSet within a NSDictionary. Yes you can achieve this by archiving it into an NSData also, but that's not exactly nice either. – PKCLsoft Jun 24 '15 at 02:54
  • Another reason would be to shuffle the indexes. – Cœur Jul 15 '15 at 00:58
  • 1
    And yet another to access indices by index. – insys Dec 06 '16 at 08:14
13
NSIndexSet *selectedItems = [aTableView selectedRowIndexes];

NSMutableArray *selectedItemsArray=[NSMutableArray array];
    [selectedItems enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
        [selectedItemsArray addObject:[NSNumber numberWithInteger:idx]];
    }];
Luc-Olivier
  • 2,886
  • 24
  • 24
3

With swift you can do the following

extension NSIndexSet {
    func toArray() -> [Int] {
        var indexes:[Int] = [];
        self.enumerateIndexesUsingBlock { (index:Int, _) in
            indexes.append(index);
        }
        return indexes;
    }
}

then you can do

selectedItems.toArray()
Chad Scira
  • 9,075
  • 3
  • 49
  • 48
1

I did it by creating a category on NSIndexSet. This kept it small and efficient, requiring very little code on my part.

My interface (NSIndexSet_Arrays.h):

/**
 *  Provides a category of NSIndexSet that allows the conversion to and from an NSDictionary
 *  object.
 */
@interface NSIndexSet (Arrays)

/**
 *  Returns an NSArray containing the contents of the NSIndexSet in a format that can be persisted.
 */
- (NSArray*) arrayRepresentation;

/**
 *  Initialises self with the indexes found wtihin the specified array that has previously been
 *  created by the method @see arrayRepresentation.
 */
+ (NSIndexSet*) indexSetWithArrayRepresentation:(NSArray*)array;

@end

and the implementation (NSIndexSet_Arrays.m):

#import "NSIndexSet_Arrays.h"

@implementation NSIndexSet (Arrays)

/**
 *  Returns an NSArray containing the contents of the NSIndexSet in a format that can be persisted.
 */
- (NSArray*) arrayRepresentation {
    NSMutableArray *result = [NSMutableArray array];

    [self enumerateRangesUsingBlock:^(NSRange range, BOOL *stop) {
        [result addObject:NSStringFromRange(range)];
    }];

    return [NSArray arrayWithArray:result];
}

/**
 *  Initialises self with the indexes found wtihin the specified array that has previously been
 *  created by the method @see arrayRepresentation.
 */
+ (NSIndexSet*) indexSetWithArrayRepresentation:(NSArray*)array {
    NSMutableIndexSet *result = [NSMutableIndexSet indexSet];

    for (NSString *range in array) {
        [result addIndexesInRange:NSRangeFromString(range)];
    }

    return result;
}


@end
PKCLsoft
  • 1,349
  • 2
  • 25
  • 34
0

Here is the sample code:

NSIndexSet *filteredObjects = [items indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {do testing here}];

NSArray *theObjects = [theItems objectsAtIndexes:filteredObjects]

Availability Available in iOS 2.0 and later.

Ankush soni
  • 1,325
  • 1
  • 13
  • 29