I have some code that was originally written as:
+(double)averageOfArray:(NSArray*)array fromIndex:(int)from toIndex:(int)to{
if (to < 0) return 0;
if (to > array.count) return 0;
double sum = 0.0;
for (long i = from; i < to; i++){
sum += [array[i] doubleValue];
}
return sum/(double)(to-from);
}
But I am trying to write it so that it's more efficient. I don't know if this will be faster or not, but one idea is to create a subarray and then calling valueForKeyPath:@"sum.self"
like this:
...
NSArray *t = [array subarrayWithRange:NSMakeRange(from, to-from)];
double sum = [[t valueForKeyPath:@"sum.self"] doubleValue];
return sum/(double)(to-from);
But this is throwing an error:
Thread 1: Exception: "[<__NSCFNumber 0xd99f8c3636814118> valueForUndefinedKey:]: this class is not key value coding-compliant for the key sum."
Looking at the debugger it shows my NSArray *t
as t = (__NSArrayl_Transfer *) @"500 elements"
. But when I look at an array that I've created like this NSArray *testArray = @[@0.1, @0.2, @0.3, @0.4 @0.5, @0.6];
then that shows up as as testArray = (__NSArrayl *) @"6 elements"
. I'm assuming that for some reason these underlying types are where the problem is.
I've tried creating a new array by doing this:
NSArray *t = [[NSArray alloc] initWithArray:[array subarrayWithRange:NSMakeRange(from, to-from)] copyItems:YES];`
But that does not fix the issue. What am I failing to understand?
When a key path contains a collection operator, any portion of the key path preceding the operator, known as the left key path, indicates the collection on which to operate relative to the receiver of the message. If you send the message directly to a collection object, such as an
NSArray
instance, the left key path may be omitted.The portion of the key path after the operator, known as the right key path, specifies the property within the collection that the operator should work on. All the collection operators except
@count
require a right key path.Operator key path format
keypathToCollection.@collectionOperator.keypathToProperty |_________________| |_________________| |_______________| Left key path Operator Right key path
@
.@count
).Because you forgot to use @
prefix, the following code ...
double sum = [[t valueForKeyPath:@"sum.self"] doubleValue];
... tries to get sum
from every NSNumber *
in the array. And then you get:
Thread 1: Exception: "[<__NSCFNumber 0xd99f8c3636814118> valueForUndefinedKey:]: this class is not key value coding-compliant for the key sum."
Just add the @
prefix to the collection operator and you'll be fine:
double sum = [[t valueForKeyPath:@"@sum.self"] doubleValue];