Skip to content

Instantly share code, notes, and snippets.

@douglashill
Created May 7, 2016 14:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save douglashill/ba88d078564f7de4c20c732598bdf80e to your computer and use it in GitHub Desktop.
Save douglashill/ba88d078564f7de4c20c732598bdf80e to your computer and use it in GitHub Desktop.
Linked list with an array interface. Can be used for implicit linked lists like superviews or the responder chain.
@import Foundation;
NS_ASSUME_NONNULL_BEGIN
@interface DHLazyLinkedList<ObjectType> : NSArray<ObjectType>
- (instancetype)initWithRootObject:(ObjectType)rootObject nextObjectBlock:(ObjectType _Nullable (^)(ObjectType))next NS_DESIGNATED_INITIALIZER;
- (nullable ObjectType)objectAfterObject:(ObjectType)object;
@end
NS_ASSUME_NONNULL_END
#import "DHLazyLinkedList.h"
NS_ASSUME_NONNULL_BEGIN
@interface DHLazyLinkedList<ObjectType> ()
@property (nonatomic, strong, readonly) id rootObject;
@property (nonatomic, copy, readonly) ObjectType _Nullable (^next)(ObjectType);
@end
NS_ASSUME_NONNULL_END
@implementation DHLazyLinkedList
- (instancetype)init {
return [self initWithRootObject:nil nextObjectBlock:nil];
}
- (instancetype)initWithObjects:(const id _Nonnull __unsafe_unretained *)objects count:(NSUInteger)cnt {
return [self initWithRootObject:nil nextObjectBlock:nil];
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
return [self initWithRootObject:nil nextObjectBlock:nil];
}
- (instancetype)initWithRootObject:(id)rootObject nextObjectBlock:(id (^)(id))next {
self = [super init];
if (self == nil) return nil;
_rootObject = rootObject;
_next = [next copy];
return self;
}
- (id)objectAfterObject:(id)object {
return [self next](object);
}
- (NSUInteger)count {
id object = [self rootObject];
NSUInteger count = 0;
NSMutableSet *foundObjects = [NSMutableSet set];
while (object) {
if ([foundObjects containsObject:object]) {
return INFINITY;
}
++count;
[foundObjects addObject:object];
object = [self objectAfterObject:object];
}
return count;
}
- (id)objectAtIndex:(NSUInteger)idx {
id object = [self rootObject];
for (; idx > 0; --idx) {
object = [self objectAfterObject:object];
}
return object;
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment