Thomas Albert
Thomas Albert

Reputation: 277

Collection operator for summing a NSDictionary's values

Is there a simple way using KVO and collection operators, that I can sum the total value of a NSDictionary like { ID: NSNumber }?

Example:

@{
  "my_ID_abcd": @(8),
  "my_ID_efgh": @(2),
  "my_ID_ijkl": @(3)
}

Would give 13 as a result.

Indeed @count doesn't return what I want, and @sum doesn't work here.. [email protected] neither...

I need to check the sum in a NSPredicate...

Thanks!

Upvotes: 0

Views: 63

Answers (1)

Larme
Larme

Reputation: 26066

A way to do that would be to use a SUBQUERY(,,) & FUNCTION(,):

NSDictionary *dict = @{ @"my_ID_abcd": @(8),
                        @"my_ID_efgh": @(2),
                        @"my_ID_ijkl": @(3)};
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SUBQUERY(FUNCTION(SELF, 'allValues'), $idsValues, $idsValues = $idsValues)[email protected] = %d", value];

BOOL pass = [predicate evaluateWithObject:dict];

From what I tried, you can't really chain two operators (ie @sum & @allValues, so I used a SUBQUERY:

SUBQUERY(allValues, $idsAllValues, $idsAllValues = $idsAllValues)

Since, you need a "true/false" on the last one, I used a simple comparaison against itself.

And I used FUNCTION to build the array of values.

That way, in the end, I can call @sum on it.

I'm not very familiar with SUBQUERY & FUNCTION, maybe the call could be simplified.

If you could use predicateWithBlock:, it would be much simpler though:

NSPredicate *withBlock = [NSPredicate predicateWithBlock:^BOOL(id  _Nullable evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings) {
    NSInteger sum = [[[evaluatedObject allValues] valueForKeyPath:@"@sum.self"] integerValue];
    return sum == value;
}];

Upvotes: 1

Related Questions