views:

256

answers:

3

Is there something similar to a circular linked list available in Cocoa?

I know that an NSArray is ordered - but I don't think I can use 'nextItem' or 'previousItem' - correct? Furthermore, I need the nextItem of the last item to be the first item.

I could add my own nextItem and previousItem methods, but I'm surprised if Apple haven't implemented something suitable already. I can't find it though if they have.

+1  A: 

I'm not aware of any such circular list data structure. Your idea about implementing it manually seems like a good idea. I would use a category:

@implementation NSArray (myCircularList)

-(id)nextItem;
-(id)previousItem;
darren
+2  A: 

While you can certainly use a category to add the behavior to NSArray (as @darren suggests), it's possible that you might actually need a true circular buffer. If that's the case, check out the CHDataStructures framework. Besides a CHCircularBufferStack, there's also a CHCircularBufferQueue and a CHCircularBufferDeque.

Dave DeLong
Is it possible to bind an NSArray to a CHData Structure? If so, it's definitely worth looking into them.
Ben Packard
NSArrayController, I mean.
Ben Packard
I haven't explicitly coded for such behavior, so if you can't, it's not yet supported. However, I've been planning to transform the abstract circular buffer parent class into a subclass of NSMutableArray, which would probably provide some of this functionality for free. (Free to you, not me as the author...)
Quinn Taylor
Also, note that my circular buffer is not exactly a first-points-to-last (and vice versa) structure. It's basically a wrapped C array where the true index is abstracted from the user. The intent is to make it cheap to insert and remove at either end, since that's what you do most with a stack/queue/deque. Perhaps modifying my doubly-linked list could provide the exact behavior you're looking for?
Quinn Taylor
A: 

You could also use something like

id foo = [array objectAtIndex:i % [array count]];

So to get from item i to the next item (or in case of last item to the very first item) just increase the index i by one. (for the previous item, simply decrease i by one) The modulo operator paired with the array length makes the array wrap around.

While not a very clean approach, it should do the trick without subclassing/categories. You'd always need to know the current index, though. :(

Regexident