Last active
August 29, 2015 13:55
-
-
Save mmackh/8780862 to your computer and use it in GitHub Desktop.
Ordered NSCountedSet. Subclassing and overwrite `- (id)keyForObject:(id)object` to specify your own keys for objects.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// PCCountedObjectContainer.h | |
// Slingshot | |
// | |
// Created by Maximilian Mackh on 02/02/14. | |
// Copyright (c) 2014 Professional Consulting & Trading GmbH. All rights reserved. | |
// | |
#import <Foundation/Foundation.h> | |
@interface PCCountedObjectContainer : NSObject | |
- (instancetype)initWithContainer:(PCCountedObjectContainer *)container; | |
- (void)addObject:(id)object; | |
- (void)insertObject:(id)object atIndex:(NSInteger)index; | |
- (void)removeObject:(id)object; | |
- (void)addAllObjectsFromContainer:(PCCountedObjectContainer *)container; | |
- (void)removeAllObjectsFromContainer:(PCCountedObjectContainer *)container; | |
- (NSInteger)countForObject:(id)object; | |
- (NSArray *)allObjects; | |
- (NSInteger)count; | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// PCCountedObjectContainer.m | |
// Slingshot | |
// | |
// Created by Maximilian Mackh on 02/02/14. | |
// Copyright (c) 2014 Professional Consulting & Trading GmbH. All rights reserved. | |
// | |
#import "PCCountedObjectContainer.h" | |
typedef NS_ENUM(NSInteger, PCCountedObjectMethod) | |
{ | |
PCCountedObjectMethodAdd, | |
PCCountedObjectMethodRemove | |
}; | |
@implementation PCCountedObjectContainer | |
{ | |
NSMutableDictionary *_objectCounter; | |
NSMutableArray *_objects; | |
} | |
- (instancetype)init | |
{ | |
self = [super init]; | |
if (!self) return nil; | |
_objectCounter = [NSMutableDictionary new]; | |
_objects = [NSMutableArray new]; | |
return self; | |
} | |
- (instancetype)initWithContainer:(PCCountedObjectContainer *)container | |
{ | |
self = [self init]; | |
if (!self) return nil; | |
NSInteger index = 0; | |
for (id object in container.allObjects) | |
{ | |
NSInteger cycles = [container countForObject:object]; | |
while (cycles --> 0) | |
{ | |
id targetObject = [container.allObjects objectAtIndex:index]; | |
[self addObject:targetObject]; | |
} | |
index++; | |
} | |
return self; | |
} | |
- (void)addObject:(id)object | |
{ | |
[self modifyMappingForObject:object method:PCCountedObjectMethodAdd index:NSNotFound]; | |
} | |
- (void)addAllObjectsFromContainer:(PCCountedObjectContainer *)container | |
{ | |
for (id object in [container allObjects]) | |
{ | |
NSInteger cycles = [container countForObject:object]; | |
while (cycles --> 0) | |
{ | |
[self addObject:object]; | |
} | |
} | |
} | |
- (void)removeAllObjectsFromContainer:(PCCountedObjectContainer *)container | |
{ | |
for (id object in [container allObjects]) | |
{ | |
NSInteger cycles = [container countForObject:object]; | |
while (cycles --> 0) | |
{ | |
[self removeObject:object]; | |
} | |
} | |
} | |
- (void)insertObject:(id)object atIndex:(NSInteger)index | |
{ | |
[self modifyMappingForObject:object method:PCCountedObjectMethodAdd index:index]; | |
} | |
- (void)removeObject:(id)object | |
{ | |
[self modifyMappingForObject:object method:PCCountedObjectMethodRemove index:NSNotFound]; | |
} | |
- (void)modifyMappingForObject:(id)object method:(PCCountedObjectMethod)method index:(NSInteger)index | |
{ | |
id key = [self keyForObject:object]; | |
if (_objectCounter[key]) | |
{ | |
NSInteger counter = [_objectCounter[key] integerValue]; | |
counter = (method == PCCountedObjectMethodAdd) ? (counter + 1) : (counter - 1); | |
_objectCounter[key] = @(counter); | |
} | |
if (method == PCCountedObjectMethodAdd && !_objectCounter[key]) | |
{ | |
_objectCounter[key] = @(1); | |
if (index == NSNotFound) | |
{ | |
[_objects addObject:object]; | |
} | |
else | |
{ | |
[_objects insertObject:object atIndex:index]; | |
} | |
return; | |
} | |
if (method == PCCountedObjectMethodAdd && _objectCounter[key]) | |
{ | |
if (index != NSNotFound) | |
{ | |
[_objects removeObject:object]; | |
[_objects insertObject:object atIndex:index]; | |
} | |
} | |
if (method == PCCountedObjectMethodRemove && ![_objectCounter[key] integerValue]) | |
{ | |
[_objectCounter removeObjectForKey:key]; | |
[_objects removeObject:object]; | |
} | |
} | |
- (NSInteger)countForObject:(id)object | |
{ | |
id key = [self keyForObject:object]; | |
if (_objectCounter[key]) | |
{ | |
return [_objectCounter[key] integerValue]; | |
} | |
return 0; | |
} | |
- (NSArray *)allObjects | |
{ | |
return _objects; | |
} | |
- (NSInteger)count | |
{ | |
return _objects.count; | |
} | |
- (id)keyForObject:(id)object | |
{ | |
return @([object hash]).stringValue; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment