Словарь, по сути, уже имеет эту функциональность. Его ключи представляют собой набор, поэтому вы можете создать словарь для хранения объектов с ключами любого интересующего вас атрибута:
[NSDictionary dictionaryWithObjects:arrayOfObjects
forKeys:[arrayOfObjects valueForKey:theAttribute]];
Если вы запросите у словаря allValues
сейчас, у вас будет только один объект для каждого атрибута. Я должен отметить, что с этой процедурой более поздние объекты будут сохранены в пользу более ранних. Если порядок вашего исходного массива значителен, измените его перед созданием словаря.
На самом деле вы не можете поместить эти объекты в NSSet
, потому что NSSet
будет использовать методы isEqual:
и hash
объектов, чтобы определить, должны ли они быть членами, а не ключевой атрибут (конечно, вы можете переопределить эти методы, если это ваш собственный класс, но это, вероятно, помешает их поведению в других коллекциях).
Если вы действительно чувствуете, что вам нужен набор, вам придется написать свой собственный класс. Вы можете создать подкласс NSSet
, но общепринятое мнение состоит в том, что составление коллекций Cocoa намного проще, чем создание подкласса. По сути, вы пишете класс, который охватывает любые интересующие вас методы набора. Вот (довольно неполный и полностью непроверенный) набросок:
@interface KeyedMutableSet : NSObject
/* This selector is performed on any object which is added to the set.
* If the result already exists, then the object is not added.
*/
@property (assign, nonatomic) SEL keySEL;
- (id)initWithKeySEL:(SEL)keySEL;
- (id)initWithArray:(NSArray *)initArray usingKeySEL:(SEL)keySEL;
- (void)addObject:(id)obj;
- (NSArray *)allObjects;
- (NSArray *)allKeys;
- (BOOL)containsObject:(id)obj;
- (NSUInteger)count;
-(void)enumerateObjectsUsingBlock:(void (^)(id, BOOL *))block;
// And so on...
@end
#import "KeyedMutableSet.h"
@implementation KeyedMutableSet
{
NSMutableArray * _objects;
NSMutableSet * _keys;
}
- (id)initWithKeySEL:(SEL)keySEL
{
return [self initWithArray:nil usingKeySEL:keySEL];
}
- (id)initWithArray:(NSArray *)initArray usingKeySEL:(SEL)keySEL
{
self = [super init];
if( !self ) return nil;
_keySEL = keySEL;
_objects = [NSMutableArray array];
_keys = [NSMutableSet set];
for( id obj in initArray ){
[self addObject:obj];
}
return self;
}
- (void)addObject:(id)obj
{
id objKey = [obj performSelector:[self keySEL]];
if( ![keys containsObject:objKey] ){
[_keys addObject:objKey];
[_objects addObject:obj];
}
}
- (NSArray *)allObjects
{
return _objects;
}
- (NSArray *)allKeys
{
return [_keys allObjects];
}
- (BOOL)containsObject:(id)obj
{
return [_keys containsObject:[obj performSelector:[self keySEL]]];
}
- (NSUInteger)count
{
return [_objects count];
}
- (NSString *)description
{
return [_objects description];
}
-(void)enumerateObjectsUsingBlock:(void (^)(id, BOOL *))block
{
for( id obj in _objects ){
BOOL stop = NO;
block(obj, &stop);
if( stop ) break;
}
}
@end
person
jscs
schedule
07.03.2013
type
? Это строка, число, объект? - person CodaFi   schedule 07.03.2013type
возвращаютYES
изisEqual:
, тогда все, что вам нужно сделать, это создать набор из массива и все готово. Но поскольку это не так, вы должны написать свою собственную обработку. - person rmaddy   schedule 07.03.2013