I have an NSArray inside an NSArray so:
@[
@[ @1, @2, @3 ],
@[ @7, @6 ]
]
How can I use the method valueForKeyPath:
to get the number of items in each array, so this:
@[ @3, @2 ]
I have tried [array valueForKeyPath:@"@count"]
but that provides the same answer as [array count]
(so 2) as does [array valueForKeyPath:@"count"]
.
Use the @unionOfObjects
and @count
KVC collection operators in conjunction:
NSArray *counts = [array valueForKeyPath:@"@unionOfObjects.@count"];
Logging counts
in this case yields:
counts = (
3,
2
)
Calling valueForKey:
and its variants on an NSArray
instance typically is used to return an array formed from the result of calling valueForKey:
on each element in the receiver. So, [array valueForKey:@"count"]
won't return the value returned by -[NSArray count]
but rather will call valueForKey:@"count"
on each of its elements. Arrays nested inside others won't behave any differently, so we can't use @"count"
as our key path directly as it will try to delegate that calculation to each of its elements. Using @"@count"
as the key path won't work, either, because it operates on the key to its left, which is implied to be the receiver of the valueForKeyPath:
method when no other key path is specified.
What we need is a way to specify that the @count
operator should count not the enclosing array but the elements thereof. Using the @unionOfObjects
collection operator in our key path accomplishes this. If we have a key path such as:
@unionOfObjects.$COLLECTION.$REST_OF_KEYPATH
Then the result returned will be the array formed by the results of sending each element of $COLLECTION
a valueForKeyPath:
message with $REST_OF_KEYPATH
as the argument. One last fact - when the receiver of a valueForKeyPath:
message is itself a collection, then $COLLECTION
can be specified in the key path with the string self
.
Accordingly, our key path should look like:
@"@unionOfObjects.self.@count"
This specifies that an array will be returned with each element being the result of sending -valueForKeyPath:@"@count"
to each element in the receiver. Finally, and I'm not sure about the advisability of this, but it seems that self can be removed from the keypath entirely so long as the @unionOfObjects
operator is not the only component of the key path. In this case, it substitutes for the @unionOfObjects.$COLLECTION
component of the key path.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With