4

Is there really no API for using NSIndexPath to traverse/access a nested array construct in the iOS SDK? I've looked in the docs for both NSIndexPath and NSArray?

For example:

NSArray *nested = @[
    @[
        @[@1, @2], @[@10, @20]
    ],
    @[
        @[@11, @22], @[@110, @220]
    ],
    @[
        @[@111, @222], @[@1110, @2220]
    ]
];

If I wanted to model the access path to @222, I could assemble:

NSIndexPath *path = [[[NSIndexPatch indexPathWithIndex: 2] indexPathByAddingIndex: 0] indexPathByAddingIndex: 1];

So do I have to write my own recursive accessor?

id probe = nested;
for (NSInteger position = 0; position < path.length; position++) {
    probe = probe[path indexAtPosition: position];
}

It would amaze me that Apple went this far to actually model the construct, but then not provide an API to bridge the two together. I would expect a method on either NSArray or NSIndexPath which allowed one to do something like:

id value = [nested objectAtIndexPath: path];

Or maybe there's a more idiomatic twist I'm missing?


UPDATE:

I chose to follow the advice of @CrimsonChris and put together the following:

NSArray+NestedAccess.h

#import <Foundation/Foundation.h>
@interface NSObject (NestedAccess)
- (id) objectAtPath: (NSIndexPath*) path;
@end

NSArray+NestedAccess.c

#import "NSArray+NestedAccess.h"
@implementation NSArray (NestedAccess)
- (id) objectAtPath: (NSIndexPath*) path {
    id probe = self;
    for (NSInteger position = 0; position < path.length; position++) {
        probe = ((NSArray*)probe)[path indexAtPosition: position];
    }
    return probe;
}
@end
Travis Griggs
  • 21,522
  • 19
  • 91
  • 167

2 Answers2

2

Sounds like you want a category for NSIndexPath! NSIndexPath is not designed to "just work" with NSArrays. It is generic enough to be used in multiple kinds of data structures.

CrimsonChris
  • 4,651
  • 2
  • 19
  • 30
  • Wish there was an example of doing that. I've not experienced authoring my own category/extensions yet. If there was, I'd give this one the answer. – Travis Griggs May 07 '14 at 18:10
  • Apple provides categories for `NSIndexPath` for use in UITableViews and UICollectionViews. That's where `row`, `section`, and `item` come from. – CrimsonChris May 07 '14 at 18:22
0

Just use indexing:

NSLog (@"nested 222: %@", nested[2][0][1]);

NSLog output:

nested 222: 222

But perhaps I don't understand what you mean by:

If I wanted to model the access path to @222, I could assemble:

If you want to use NSIndexPath why not create a subclass that performs array indexing. Or create a helper class or method.

zaph
  • 111,848
  • 21
  • 189
  • 228