Un dizionario ha essenzialmente questa funzionalità già. I tasti sono un insieme, in modo da poter creare il dizionario per contenere gli oggetti, calettati con qualsiasi attributo che ti interessa:
[NSDictionary dictionaryWithObjects:arrayOfObjects
forKeys:[arrayOfObjects valueForKey:theAttribute]];
Se chiedete il dizionario per allValues
ora, si dispone di un solo oggetto per ogni attributo. Dovrei menzionare che con questa procedura, gli oggetti successivi saranno mantenuti in favore di prima. Se l'ordine dell'array originale è significativo, invertirlo prima di creare il dizionario.
non si può effettivamente mettere quegli oggetti in un NSSet
, perché il NSSet
userà degli oggetti isEqual:
e hash
metodi per determinare se debbano essere membri, piuttosto che l'attributo chiave (naturalmente, è possibile ignorare questi metodi se questa è la tua classe, ma probabilmente interferirebbe con il loro comportamento in altre raccolte).
Se davvero senti che hai bisogno di un set, dovrai scrivere la tua classe. È possibile creare una sottoclasse di NSSet
, ma la saggezza convenzionale è che la composizione delle raccolte di Cocoa è molto più semplice rispetto alla sottoclasse. In sostanza, si scrive una classe che copre tutti i metodi set che ti interessa Ecco un (abbastanza incompleta e totalmente non testato) schizzo:.
@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
fonte
2013-03-07 20:41:30
Vuoi solo la prima istanza di ogni tipo? O un'istanza arbitraria? Questa non è una mappatura evidente da un array a un set. –
Iterate attraverso l'array e aggiungete tali oggetti in un NSMutableSet. – ZhangChn
Qual è il tipo di 'tipo'? È una stringa, un numero, un oggetto? – CodaFi