Reputation: 5655
I have the following two arrays.
NSArray *array1=[[NSArray alloc]initWithObjects:@"ABC",@"DEF", nil];
NSArray *array2=[[NSArray alloc]initWithObjects:@"ABC",@"123",@"DEF",@"DEF", nil];
Now i have to search each array1's object and in array2 and need to get the matched indexes. And my application contains more than one thousand objects in array2.
Please suggest the best possible way other than putting second for loop in first for loop
for (int i=0; i<array1.count; i++)
{
//Need to search the [array1 objectAtIndex:i] string in array2 and need to get the matched indexes into an array in best optimised way here.
NSMutableArray *matchedIndexesArray=[[NSMutableArray alloc]init];
NSString *stringToSearch=[array1 objectAtIndex:i];
//here i can put another array like below to get the matched indexes..but is there any optimized way other than this for loop here? or is there any simple inbuilt method to get the matched objects into an array here.
for (int j=0; j<array2.count; j++)
{
if ([stringToSearch isEqualToString:[array2 objectAtIndex:j]])
{
[matchedIndexesArray addObject:[NSString stringWithFormat:@"%d",j]];
}
}
NSLog(@"matchedIndexesArray-->%@<--",matchedIndexesArray);
//I will use this matchedIndexesArray here further processing...
//
//
//
//Large Code Here
//
//
//
}
Upvotes: 3
Views: 5304
Reputation: 32076
NSArray *a = @[@"123", @"456", @"ABC", @"DEF"];
NSArray *b = @[@"123", @"ABC", @"---"];
NSIndexSet *indexes = [a indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop)
{
return [b containsObject:obj]
}];
NSLog(@"%@", indexes);
Upvotes: 4
Reputation: 540145
According to the NSSet documentation, membership testing is faster for sets than for arrays.
Therefore it makes sense to convert array1
to a set first:
NSSet *set1 = [NSSet setWithArray:array1];
and then test each object of array2
for membership in the set. This can be conveniently
done as
NSIndexSet *matchingIndexes = [array2 indexesOfObjectsPassingTest:^BOOL(NSString *obj, NSUInteger idx, BOOL *stop) {
return [set1 containsObject:obj];
}];
Show all matching indexes:
[matchingIndexes enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
NSLog(@"%ld", (long)idx);
}];
// Output: 0, 2, 3
UPDATE: (after question edit) No, there is no method to fill an NSArray
with the indices of matching objects. But there is a method to fill an NSIndexSet
. NSIndexSet
is a special collection to store indices
into some other data structure, such as an array. Then your code would look like
for (NSString *stringToSearch in array1) {
NSIndexSet *matchingIndexes = [array2 indexesOfObjectsPassingTest:^BOOL(NSString *obj, NSUInteger idx, BOOL *stop) {
return [stringToSearch isEqualToString:obj];
}];
NSLog(@"matchingIndexes: %@", matchingIndexes);
// Work with matchingIndex, for example enumerate all indices:
[matchingIndexes enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
NSLog(@"%ld", (long)idx);
}];
}
But I do not know if it makes much difference in performance.
Upvotes: 11
Reputation: 15335
NSArray *array1=[[NSArray alloc]initWithObjects:@"ABC",@"DEF", nil];
NSArray *array2=[[NSArray alloc]initWithObjects:@"ABC",@"123",@"DEF",@"DEF", nil];
for (int i=0; i<array1.count; i++){
for (int j=0; j<array2.count; j++) {
if ([[array1 objectAtIndex:i] isEqualToString: [array2 objectAtIndex:j]]) {
NSLog(@"Matched Indexes %d %@", i, [array1 objectAtIndex:i] );
}
}
}
Upvotes: 0