How to get indexes from NSIndexset into an NSArray in cocoa?
Asked Answered
G

5

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?

Gezira answered 22/9, 2010 at 20:7 Comment(3)
i have a method getting an NSArray as parameter to delete multiple records selected from the tableviewGezira
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?Dimorphism
is there not a method on NSArray which returns the elements in provided NSIndexSex?Drawtube
D
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.

Dimorphism answered 22/9, 2010 at 20:10 Comment(5)
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....Gezira
It's in the docs: developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/…October
@Dimorphism 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.Bottom
Another reason would be to shuffle the indexes.Diplopod
And yet another to access indices by index.Novocaine
D
14
NSIndexSet *selectedItems = [aTableView selectedRowIndexes];

NSMutableArray *selectedItemsArray=[NSMutableArray array];
    [selectedItems enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
        [selectedItemsArray addObject:[NSNumber numberWithInteger:idx]];
    }];
Disc answered 11/5, 2014 at 15:58 Comment(0)
M
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()
Meshach answered 10/3, 2015 at 12:42 Comment(0)
B
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;

/**
 * Returns an array of NSNumber objects representing each index in the set.
 */
- (NSArray<NSNumber*>*) arrayOfNumbersRepresentation;

/**
 *  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];
}

/**
 * Returns an array of NSNumber objects representing each index in the set.
 */
- (NSArray<NSNumber*>*) arrayOfNumbersRepresentation {
    NSMutableArray<NSNumber*> *result = [NSMutableArray array];

    [self enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL * _Nonnull stop) {
        [result addObject:[NSNumber numberWithInteger:idx]];
    }];

    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
Bottom answered 24/6, 2015 at 4:10 Comment(0)
W
1

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.

Weissman answered 1/9, 2015 at 9:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.