DZone
Mobile Zone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
  • Refcardz
  • Trend Reports
  • Webinars
  • Zones
  • |
    • Agile
    • AI
    • Big Data
    • Cloud
    • Database
    • DevOps
    • Integration
    • IoT
    • Java
    • Microservices
    • Open Source
    • Performance
    • Security
    • Web Dev
DZone > Mobile Zone > Key-Value Coding Aggregation Operations on Collections

Key-Value Coding Aggregation Operations on Collections

Stop overlooking Key-Value Coding! Use this handy reference, because if you have ever worked with SQL queries and the aggregate functions, you know you need it.

Peter Molnar user avatar by
Peter Molnar
·
Dec. 12, 16 · Mobile Zone · Tutorial
Like (2)
Save
Tweet
3.85K Views

Join the DZone community and get the full member experience.

Join For Free

If you have ever worked with SQL queries and the aggregate functions (or in worst case with spreadsheet applications like Excel or Numbers), this topic will be familiar to you.

It is usually overlooked, but the Key-Value Coding can also benefit from those functions on collections, like NSArray or NSSet. Obviously, the type should support those operations, for example, it would be barely successful to ask for sum on a set containing NSStrings.

Aggregate functions in Key-Value Coding

Let’s take a look what basic aggregation operations we have, similar to the SQL: @count, @sum, @avg, @max, and @min. There are also other operations, for the full list, you can check the documentation.

The key point here is the same method used for the Key-Value Coding, the valueForKeyPath:. If you want to use the aggregate functions on any set, you should use [anySet valueForKeyPath:@[email protected]_function.key”];. Notice, that we are using the @ symbol before the aggregate.

However, @count doesn’t make sense for me, as you can always send the count message to the set, the others could be really interesting and helpful.

Aggregate!

Let see some basic example for NSNumbers and dates. Obviously, @avg and @sum will fail on NSDates.

        NSArray *numbers = @[@6,@4,@7,@90];
        NSNumber *maxNumber = [numbers valueForKeyPath:@"@max.self"];
        NSNumber *minNumber = [numbers valueForKeyPath:@"@min.self"];
        NSNumber *sumOfNumbers = [numbers valueForKeyPath:@"@sum.self"];
        NSNumber *avgOfNumbers = [numbers valueForKeyPath:@"@avg.self"];

        NSLog(@"\nmin: %@\nmax: %@\nsum: %@\navg: %@", minNumber, maxNumber, sumOfNumbers, avgOfNumbers);

        NSDate *today = [NSDate date];
        NSArray *dates = @[today,
                               [today dateByAddingTimeInterval: -86400.0],
                               [today dateByAddingTimeInterval: 86400.0]
                               ];

        NSDate *maxDate = [dates valueForKeyPath:@"@max.self"];
        NSDate *minDate = [dates valueForKeyPath:@"@min.self"];

        NSLog(@"\nminDate: %@\nmaxDate: %@\n", maxDate, minDate);

Since the aggregate should be applied on the set, which contains the atomic structures, I used .self after the aggregate function.

The thing is getting more interesting, when you are using array of Objects, for example:

#import <Foundation/Foundation.h>
#import "PMOLottoNumbers.h"

@interface PMOTransaction : NSObject

@property NSString *name;
@property NSNumber *amount;
@property NSDate *transactionDate;

@end

@implementation PMOTransaction

@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {

        PMOTransaction *transaction1 = [[PMOTransaction alloc] init];

        transaction1.name = @"Mark";
        transaction1.amount = @1000;
        transaction1.transactionDate = today;

        PMOTransaction *transaction2 = [[PMOTransaction alloc] init];

        transaction2.name = @"Mark";
        transaction2.amount = @500;
        transaction2.transactionDate = [today dateByAddingTimeInterval: -86400.0];

        PMOTransaction *transaction3 = [[PMOTransaction alloc] init];

        transaction3.name = @"Abella";
        transaction3.amount = @99999;
        transaction3.transactionDate = [today dateByAddingTimeInterval: 86400.0];

        NSArray *transactions = @[transaction1, transaction2, transaction3];

        NSNumber *maxAmount = [transactions valueForKeyPath:@"@max.amount"];
        NSNumber *minAmount = [transactions valueForKeyPath:@"@min.amount"];
        NSNumber *sumOfAmount = [transactions valueForKeyPath:@"@sum.amount"];
        NSNumber *avgOfAmount = [transactions valueForKeyPath:@"@avg.amount"];

        NSLog(@"\nminAmount: %@\nmaxAmount: %@\nsumOfAmount: %@\navgOfAmount: %@\n", minAmount, maxAmount, sumOfAmount, avgOfAmount);

        NSString *minName = [transactions valueForKeyPath:@"@min.name"];
        NSString *maxName = [transactions valueForKeyPath:@"@max.name"];
        NSString *countName = [transactions valueForKeyPath:@"@count.name"];

        NSLog(@"\nminName: %@\nmaxName: %@\ncountName: %@", minName, maxName, countName);

    }
    return 0;
}

As you can see I created a really basic class (PMOTransaction), and 3 instances, which I added to a collection. Then I used the property names as keys, and applied the aggregate on them.

I hope this small example helps to you out in some cases when you need the minimum or a maximum from a collection.

Coding (social sciences)

Published at DZone with permission of Peter Molnar, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • To Shift Right, You Need Observability
  • Event-Driven Microservices?
  • The Importance of Semantics for Data Lakehouses
  • Purpose-Driven Microservice Design

Comments

Mobile Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • MVB Program
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends:

DZone.com is powered by 

AnswerHub logo