Enumerate NSArray using blocks to find and store a

2020-05-08 07:57发布

问题:

How could I enumerate an NSArray containing objects of multiple types, to get all the indexes where an NSString is found, then be able to refer to each index in order by saying something like...

NSString *firstOccurrence = [myArray objectAtIndex:firstOccurrence];
NSString *secondOccurrence = [myArray objectAtIndex:secondOccurrence];
NSString *thirdOccurrence = [myArray objectAtIndex:thirdOccurrence];

Thanks!

EDIT: How I'm using the code (Updated with @NJones example.)

I need the Integer value of the index where the strings are stored in the array, to update the NSUInteger property "wordDisplayed" with that value.

In my code here, I'm using a modified version of UIActionSheet to accept blocks: https://github.com/zoul/Lambda-Alert

NSIndexSet *stringLocations = [arrayInLesson indexesOfObjectsPassingTest:^(id obj, NSUInteger idx, BOOL *stop){
    return [(NSObject *)obj isKindOfClass:[NSString class]];
}];

NSArray *passingObjects = [arrayInLesson objectsAtIndexes:stringLocations];

sectionHeadersAct = [[LambdaSheet alloc] initWithTitle:@"Book 2 Lesson 1"];
[sectionHeadersAct addButtonWithTitle:@"D. E. F. & G. Teach New Letters" block:^{ 
    //Do nothing yet
}];
[sectionHeadersAct addButtonWithTitle:[passingObjects objectAtIndex:0] block:^{
    NSLog(@"First");
    wordDisplayed = theIndexOfThisStringIn_arrayInLesson;
}];
[sectionHeadersAct addButtonWithTitle:[passingObjects objectAtIndex:1] block:^{ 
    NSLog(@"Second"); 
    wordDisplayed = theIndexOfThisStringIn_arrayInLesson;
}];
[sectionHeadersAct addButtonWithTitle:[passingObjects objectAtIndex:2] block:^{ 
    NSLog(@"Third"); 
    wordDisplayed = theIndexOfThisStringIn_arrayInLesson;
}];
[sectionHeadersAct addButtonWithTitle:[passingObjects objectAtIndex:3] block:^{ 
    NSLog(@"Fourth"); 
    wordDisplayed = theIndexOfThisStringIn_arrayInLesson;
}];
[sectionHeadersAct setDismissAction:^{
    //Do nothing yet
}];
[sectionHeadersAct showInView:self.view];

回答1:

You can get an NSIndexSet of the location of objects that you define with indexesOfObjectsPassingTest:. Like so:

-(void)findStrings{
    NSArray *randomObjects = [NSArray arrayWithObjects:[NSNull null], @"String", [NSNull null], @"String", [NSNull null], nil];
    NSIndexSet *stringLocations = [randomObjects indexesOfObjectsPassingTest:^(id obj, NSUInteger idx, BOOL *stop){
        return [(NSObject *)obj isKindOfClass:[NSString class]];
    }];
    NSLog(@"strings %@",stringLocations);

        // You can get an array of just the passing objects like so:
    NSArray *passingObjects = [randomObjects objectsAtIndexes:stringLocations];
}


回答2:

Well, the enumerateObjectsUsingBlock: method of NSArray will let you enumerate the objects in the array using a block (per your request).

To test for strings, you could simply do this:

if ([itemToTest isKindOfClass:[NSString class]]) ...

And you could add each of those to a Dictionary with Object keys and Int values (or vice-versa).