Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this questionI'm trying to make an iPhone app that detects duplicate contacts. I've made a for loop to loop through an array of all the contacts (people) but it only seems to work once.
for (int i = 0; i < [people count]; i++)
{
ABRecordRef person = (ABRecordRef)[people objectAtIndex:i];
ABRecordRef person2;
NSString *firstname = (NSString*)ABRecordCopyValue(person, kABPersonFirstNameProperty);
NSString *lastname = (NSString*)ABRecordCopyValue(person, kABPersonLastNameProperty);
NSLog(@"Firstname = %@", firstname);
NSLog(@"People count = %i", [people count]);
for (int j = 0; i < [people count]; i++)
{
person2 = (ABRecordRef)[people objectAtIndex:i];
if (j != i
&& [firstname isEqualToString:(NSString*)ABRecordCopyValue(person2, kABPerso开发者_运维知识库nFirstNameProperty)]
&& [lastname isEqualToString:(NSString*)ABRecordCopyValue(person2, kABPersonLastNameProperty)])
{
//duplicate is found
NSString *name = firstname;
name = [name stringByAppendingString:@" "];
name = [name stringByAppendingString:lastname];
[duplicates addObject:name];
}
}
}
NSLog(@"Exited loop!");
The outputs of the NSLog is this:
Firstname = Bob
People count = 3
Exited loop!
I tried substituting [people count] for 3, but got the same output. I don't have a break; statement anywhere in my code, so I don't know what the problem is...
You are testing and incrementing i
in the inner loop.
Also, the inner loop should only test values of j that are less than (or alternatively, greater than) i. Currently, you are testing every pair twice.
int n = [people count]; // minor perf improvement
for (int i = 1; i < n; ++i) {
...
for (int j = 0; j < i; ++j) {
...
This also obviates the j != i
test.
For an even further improvement, instead of the inner loop, add people's names to an NSSet
and test membership of that set to identify duplicates. This is much faster for large populations.
You're testing and incrementing the i
variable in the inner loop; it should be j
:
for (int j = 0; j < [people count]; j++)
When looping like this, I generally use the other for-style looping:
for (Person *p in peopleArray) {
// do something amazing here with p.
}
Yep, for (int j = 0; i < [people count]; i++)
It's a mistake we all make, more often than we want to admit.
精彩评论