Restrict Duplicate entry in NSArray
I have an开发者_C百科 array, which contains some duplicate entries.
Firstly, is there any way to restrict duplicate entries when data getting inserted?
Secondly, if an array already having duplicate values than in some other way, we can retrieve only unique values from that array, I heard about NSSet about this, but I have no idea how to use it.
Don't use an NSSet.
You can only insert elements upon creation and cannot change the elements contained after you have created it.
If you want to add and remove objects on the fly, you can use an NSMutableSet.
Here is a demo of how to use it both NSSet and NSMutableSet, then converting the NSSet back to an NSArray (incase you want to do that):
- (void) NSMutableSetPrintTest
{
NSMutableSet *mutableSet = [[NSMutableSet alloc] init];
NSLog(@"Adding 5 objects (3 are duplicates) to NSMutableSet");
NSString *firstString = @"Hello World";
[mutableSet addObject:firstString];
[mutableSet addObject:@"Hello World"];
[mutableSet addObject:@"Goodbye World"];
[mutableSet addObject:@"Goodbye World"];
[mutableSet addObject:@"Goodbye World"];
NSLog(@"NSMutableSet now contains %d objects:", [mutableSet count]);
int j = 0;
for (NSString *string in mutableSet) {
NSLog(@"%d: %@ <%p>", j, string, string);
j++;
}
NSLog(@"Now, if we are done adding and removing things (and only want to check what is in the Set) we should convert to an NSSet for increased performance.");
NSSet *immutableSet = [NSSet setWithSet:mutableSet];
NSLog(@"NSSet now contains %d objects:", [immutableSet count]);
int i = 0;
for (NSString *string in immutableSet) {
NSLog(@"%d: %@ <%p>", i, string, string);
i++;
}
[mutableSet release]; mutableSet = nil;
NSLog(@"Now, if we are done with the sets, we can convert them back to an NSArray:");
NSArray *array = [immutableSet allObjects];
NSLog(@"NSArray contains %d objects", [array count]);
int k = 0;
for (NSString *string in array) {
NSLog(@"%d: %@ <%p>", k, string, string);
k++;
}
}
NSMutableSet
is probably the most logical thing to use.
However, be warned that a set does not maintain order of its elements (since a set, by definition, is unordered).
If that's a problem for you, then you have a couple of options:
- duplicate set functionality with an
NSMutableArray
by invokingcontainsObject:
before every call toaddObject:
(doable, but potentially slow, since arrays have O(n) search time) - use another object.
If you go with the second option, I would recommend taking a look at the excellent CHDataStructures framework, which has a subclass of NSMutableSet
called CHOrderedSet
, which is a set that maintains insertion order. (And since it's a subclass, it has the exact same API as an NSMutableSet
)
If you've heard about NSSet, did you read the documentation? The API is similar to NSArray and very straightforward. Just like NSArray vs. NSMutableArray, you would use NSMutableSet if you need on the fly membership tests.
精彩评论