DZone
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
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations

Trending

  • How to Optimize CPU Performance Through Isolation and System Tuning
  • Fun Is the Glue That Makes Everything Stick, Also the OCP
  • You’ve Got Mail… and It’s a SPAM!
  • DevOps Midwest: A Community Event Full of DevSecOps Best Practices

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 · Tutorial
Like (2)
Save
Tweet
Share
4.11K 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.

Trending

  • How to Optimize CPU Performance Through Isolation and System Tuning
  • Fun Is the Glue That Makes Everything Stick, Also the OCP
  • You’ve Got Mail… and It’s a SPAM!
  • DevOps Midwest: A Community Event Full of DevSecOps Best Practices

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • 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

Let's be friends: