2013-03-07 55 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屬性。