2013-03-07 61 views
8

如何根据属性从数组创建对象NSSet根据属性从NSArray创建NSSet

例如对象数组,每个对象具有对type属性的强引用,并且数组中存在多个每种类型。这怎么可能变成一个持有每个类型的单个对象。

+0

你只想要每种类型的第一个实例吗?或者一个任意的实例?这不是一个真正的从数组到映射的明显映射。 – 2013-03-07 02:57:02

+0

遍历数组并将这些对象添加到NSMutableSet中。 – ZhangChn 2013-03-07 02:59:51

+0

'type'的类型是什么?它是一个字符串,一个数字还是一个对象? – CodaFi 2013-03-07 03:27:06

回答

0

你可以使用:

NSSet* mySetWithUniqueItems= [NSSet setWithArray: yourArray]; 

这应该不管你的数组中的对象类型的工作,并将填充的NSSet只有一个occurence您的阵列中的任何重复的对象。

我希望这会有所帮助。

更新: 接下来最好的事情是:首先使用类名和对象属性的连接,然后使用上面的方法。

self.concatenatedArray=[NSMutableArray arrayWithCapacity:4]; 

for (TheClass* object in self.myArray) 
    [self.concatenatedArray addObject:[NSString stringWithFormat:@"%@-%@",[object class], object.theProperty]]; 

self.mySet=[NSSet setWithArray:self.concatenatedArray]; 

我不知道你会用什么的NSSet输出,但你也许可以修改拼接元素,有你在的NSSet输出所需要的信息。

+0

我想根据独特的属性值得到一组相同的对象类型。 – jarryd 2013-03-07 03:25:46

+0

这是什么意思? – 2013-03-07 03:29:54

+0

@ReyGonzales,我相信这里的复杂性在于上面的方法将创建一个NSSet,其中包含来自该数组的唯一对象。氦气正在寻求用对象级别相似的对象填充NSSet,但每个对象具有不同的属性。 – Spectravideo328 2013-03-07 03:33:31

0
NSMutableSet* classes = [[NSMutableSet alloc] init]; 
NSMutableSet* actualSet = [[NSMutableSet alloc] init]; 

for(id object in array) { 
    if([classes containsObject:[object class]] == NO) { 
     [classes addObject:[object class]]; 
     [actualSet addObject:object]; 
    }   
} 
7
NSSet *distinctSet = [NSSet setWithArray:[array valueForKeyPath:@"@distinctUnionOfObjects.property"]]; 
2

字典本质上具有这个功能了。它的按键是一组,这样你就可以创建字典什么属性,你有兴趣持有的对象,通过键入:

[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 
0

我创建了一个简单的库,称为Linq to ObjectiveC ,这是使这类问题更容易解决的一系列方法。在你的情况,你需要的Linq-to-ObjectiveC distinct方法:

NSSet* dictionary = [NSSet setWithArray:[sourceArray distinct:^id(id item) { 
    return [item type] ; 
}]]; 

这将返回一组,其中每个项目具有鲜明的type属性。