sangony
sangony

Reputation: 11696

Code optimization (combine 2 lines of code into 1)

I have tried some combinations but can't seem to get it right. I am looking to combine line 2 and 3 into one line of code.

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name == 'SSM M51 Copperhead'"];
NSArray *searchResults1 = [self.weaponsArray filteredArrayUsingPredicate:predicate];
weapons = [searchResults1 objectAtIndex:0];
if(weapons.range > SSMrange)
    SSMrange = weapons.range;

('weapons' is a class).

Upvotes: 0

Views: 127

Answers (4)

Dave FN
Dave FN

Reputation: 652

There is no need to create an array object with the filtered results only to get the first object and throw away the collection.

If you're targeting iOS 4.0 or later, NSArray provides functionality to get the index of the first object passing a test through a block.

NSUInteger indexOfObject = [self.weaponsArray indexOfObjectPassingTest:^(id obj, NSUInteger index, BOOL *stop) {
  return [[obj valueForKey:@"name"] isEqualToString:@"SSM M51 Copperhead"];
}];

The block will be executed once for each object and the array will stop processing when the block returns YES. Once you know the index of the object, you can get the value directly from you self.weaponsArray array. Just make sure you check the return value for NSNotFound.

I tried filtering an array of 1,000,000 objects and searching for the both the first and last object using the two approaches. Even when looking for the last object, the block approach was still quicker than using a predicate. I'm guessing due to the saving of not creating a filtered array.

Upvotes: 1

acorc
acorc

Reputation: 360

weapon = [[self.weaponsArray filteredArrayUsingPredicate:predicate] objectAtIndex:0];

Upvotes: 1

Taum
Taum

Reputation: 2551

How about defining a method like:

- (Weapon*)firstWeaponMatchingPredicateWithFormat:(NSString*)format
{
    NSPredicate *predicate = [NSPredicate predicateWithFormat:format];
    NSArray *searchResults1 = [self.weaponsArray filteredArrayUsingPredicate:predicate];
    return (searchResults1.count > 0 ? [searchResults1 objectAtIndex:0] : nil);
}

Call with:

Weapon *weapon = [self firstWeaponMatchingPredicateWithFormat:@"name == 'SSM M51 Copperhead'"];

Upvotes: 2

hypercrypt
hypercrypt

Reputation: 15376

weapons = [self.weaponsArray filteredArrayUsingPredicate:predicate][0];

This isn't really going to make your code any faster though.

Upvotes: 2

Related Questions