Речникът по същество вече има тази функционалност. Неговите ключове са набор, така че можете да създадете речника, който да съдържа обектите, ключове с какъвто и да е атрибут, който ви интересува:
[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