I am trying to figure out how to implement this in Objective-C.
我想弄清楚如何在Objective-C中实现它。
I want to remove the strings in an NSArray
that have appear more than once in the array.
我想删除NSArray中在数组中出现多次的字符串。
At the end I want to have an array that only has the unique lines in an array (meaning that not just the duplicates are deleted but also the original string that matches the duplicates.)
最后,我希望有一个数组只有一个数组中的唯一行(这意味着不仅删除了重复项,还删除了与重复项匹配的原始字符串。)
For example if you had the following array:
例如,如果您有以下数组:
NSArray *array = [NSArray arrayWithObjects:@"bob", @"frank", @"sarah", @"sarah", @"fred", @"corey", @"corey", nil];
I would want the new array to look like this:
我希望新数组看起来像这样:
@"bob", @"frank", @"fred"
4 个解决方案
#1
24
Use an NSCountedSet
:
使用NSCountedSet:
NSCountedSet *countedSet = [NSCountedSet setWithArray:yourArray];
NSMutableArray *finalArray = [NSMutableArray arrayWithCapacity:[yourArray count]];
for(id obj in countedSet) {
if([countedSet countForObject:obj] == 1) {
[finalArray addObject:obj];
}
}
@Caleb suggested adding a method to NSCountedSet
called -objectsWithCount:,
, which I've implemented here:
@Caleb建议在NSCountedSet中添加一个名为-objectsWithCount:的方法,我在这里实现了:
@interface NSCountedSet (JRCountedSetAdditions)
- (NSArray *) objectsWithCount:(NSUInteger) count;
@end
@implementation NSCountedSet (JRCountedSetAdditions)
- (NSArray *) objectsWithCount:(NSUInteger) count {
NSMutableArray *array = [NSMutableArray array];
for(id obj in self) {
if([self countForObject:obj] == count) {
[array addObject:obj];
}
}
return [array copy];
}
@end
Once that's done, all you need is one line:
一旦完成,您只需要一行:
NSArray *finalArray = [[NSCountedSet setWithArray:yourArray] objectsWithCount:1];
By the way, this is type-agnostic, so this will work with any Objective-C object. :-)
顺便说一句,这是类型不可知的,因此这适用于任何Objective-C对象。 :-)
#2
9
One liner : uniqueArray = [[NSSet setWithArray:duplicateArray] allObjects];
if you don't care about the ordering :D
一个衬垫:uniqueArray = [[NSSet setWithArray:duplicateArray] allObjects];如果你不关心订购:D
#3
3
A slightly different approach from Jacob's:
雅各布的方法略有不同:
NSArray *array = [NSArray arrayWithObjects:@"bob", @"frank", @"sarah", @"sarah", @"fred", @"corey", @"corey", nil];
NSCountedSet *namesSet = [[NSCountedSet alloc] initWithArray:array];
NSMutableArray *namesArray = [[NSMutableArray alloc] initWithCapacity:[array count]];
[namesSet enumerateObjectsUsingBlock:^(id obj, BOOL *stop){
if ([namesSet countForObject:obj] == 1) {
[namesArray addObject:obj];
}
}];
And
和
NSLog(@"old: %@\nNew: %@", array, namesArray);
gives:
得到:
2011-06-16 18:10:32.783 SetTest[1756:903] old: (
bob,
frank,
sarah,
sarah,
fred,
corey,
corey
)
New: (
frank,
fred,
bob
)
Blocks are your friends! And since NSCountedSet
is a subclass of NSSet
you can use the block methods that are available there.
积木是你的朋友!由于NSCountedSet是NSSet的子类,因此您可以使用那里可用的块方法。
#4
2
Here is the simplest approach to remove duplicate strings:
以下是删除重复字符串的最简单方法:
NSArray *array = [NSArray arrayWithObjects:@"bob", @"frank", @"sarah", @"sarah", @"fred", @"corey", @"corey", nil];
NSArray *distintStrings = [array valueForKeyPath:@"@distinctUnionOfObjects.self"];
#1
24
Use an NSCountedSet
:
使用NSCountedSet:
NSCountedSet *countedSet = [NSCountedSet setWithArray:yourArray];
NSMutableArray *finalArray = [NSMutableArray arrayWithCapacity:[yourArray count]];
for(id obj in countedSet) {
if([countedSet countForObject:obj] == 1) {
[finalArray addObject:obj];
}
}
@Caleb suggested adding a method to NSCountedSet
called -objectsWithCount:,
, which I've implemented here:
@Caleb建议在NSCountedSet中添加一个名为-objectsWithCount:的方法,我在这里实现了:
@interface NSCountedSet (JRCountedSetAdditions)
- (NSArray *) objectsWithCount:(NSUInteger) count;
@end
@implementation NSCountedSet (JRCountedSetAdditions)
- (NSArray *) objectsWithCount:(NSUInteger) count {
NSMutableArray *array = [NSMutableArray array];
for(id obj in self) {
if([self countForObject:obj] == count) {
[array addObject:obj];
}
}
return [array copy];
}
@end
Once that's done, all you need is one line:
一旦完成,您只需要一行:
NSArray *finalArray = [[NSCountedSet setWithArray:yourArray] objectsWithCount:1];
By the way, this is type-agnostic, so this will work with any Objective-C object. :-)
顺便说一句,这是类型不可知的,因此这适用于任何Objective-C对象。 :-)
#2
9
One liner : uniqueArray = [[NSSet setWithArray:duplicateArray] allObjects];
if you don't care about the ordering :D
一个衬垫:uniqueArray = [[NSSet setWithArray:duplicateArray] allObjects];如果你不关心订购:D
#3
3
A slightly different approach from Jacob's:
雅各布的方法略有不同:
NSArray *array = [NSArray arrayWithObjects:@"bob", @"frank", @"sarah", @"sarah", @"fred", @"corey", @"corey", nil];
NSCountedSet *namesSet = [[NSCountedSet alloc] initWithArray:array];
NSMutableArray *namesArray = [[NSMutableArray alloc] initWithCapacity:[array count]];
[namesSet enumerateObjectsUsingBlock:^(id obj, BOOL *stop){
if ([namesSet countForObject:obj] == 1) {
[namesArray addObject:obj];
}
}];
And
和
NSLog(@"old: %@\nNew: %@", array, namesArray);
gives:
得到:
2011-06-16 18:10:32.783 SetTest[1756:903] old: (
bob,
frank,
sarah,
sarah,
fred,
corey,
corey
)
New: (
frank,
fred,
bob
)
Blocks are your friends! And since NSCountedSet
is a subclass of NSSet
you can use the block methods that are available there.
积木是你的朋友!由于NSCountedSet是NSSet的子类,因此您可以使用那里可用的块方法。
#4
2
Here is the simplest approach to remove duplicate strings:
以下是删除重复字符串的最简单方法:
NSArray *array = [NSArray arrayWithObjects:@"bob", @"frank", @"sarah", @"sarah", @"fred", @"corey", @"corey", nil];
NSArray *distintStrings = [array valueForKeyPath:@"@distinctUnionOfObjects.self"];