views:

45

answers:

1

I have an id<NSFastEnumeration> object. I want to count the elements inside the object. How can that be achieved?

The only method NSFastEnumeration implements is:

- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len

This method returns the count I am looking for, but as I do not want to really enumerate the objects I wonder, what I could safely pass in as arguments. Would it be OK to just pass nil,nil,0? If not, what should I pass?

The Background:

I want to create an NSArray of the return values of a function, which I want to call with every element in the given collection. I want an Array of the results of enumerating a collection with a function.

id<NSFastEnumeration> enumeratable = someObject;
NSMutableArray* results = [NSMutableArray arrayWithCapacity:(#Fill in count here#)];
for (id object in enumeratable) {
    [results addObject:callFunctionOnObject(object)];
}

AS you can see I only need the count to optimize Array initialization. I am pretty aware that I could use NSMutableArray* results = [NSMutableArray array]; instead.

+2  A: 

The only way to get the length from an NSFastEnumeration is to loop through it.

int count = 0;
for (id x in enumerator)
  ++ count;
return count;

Of course this means the enumerator will be exhausted and you can't loop it again.

Also, the capacity is just a hint. There's little benefit in setting it.

KennyTM
Thanks, for your answer. I know the capacity is only a hint, but then I got curious and wanted to know. I will stick with `NSMutableArray* results = [NSMutableArray array];` then.
tonklon
*Of course this means the enumerator will be exhausted and you can't loop it again.* Does it? I can't find anywhere in the docs where it says that is true.
JeremyP
@Jeremy: Take a look at NSEnumerator, which adopts NSFastEnumeration.
KennyTM
@Kenny TM: I did check out the docs of NSEnumerator but it doesn't say that using `for(... in ...)` on an enumerator exhausts the enumerator. I have, however tried it and found that it is true.
JeremyP