0

Things like max, min, and avg can be calculated just fine,

NSExpression *maxDate = [NSExpression expressionForKeyPath:@"startDate"];
NSExpression *maxDateExpression = [NSExpression expressionForFunction:@"max:"
                                                            arguments:@[maxDate]];
NSExpressionDescription *maxDateExpressionDescription = [[NSExpressionDescription alloc] init];
[maxDateExpressionDescription setName:@"maxDate"];
[maxDateExpressionDescription setExpression:maxDateExpression];
[maxDateExpressionDescription setExpressionResultType:NSDateAttributeType];



[request setPropertiesToFetch:@[maxDateExpressionDescription]];


// Execute the fetch.
NSError *error = nil;

NSArray *objects = [context executeFetchRequest:request error:&error];
if (error) {
    // Handle the error.

    NSLog(@"Error!");
}
else {
    NSLog(@"Max date is: %@", [objects[0] objectForKey:@"maxDate"]);
]

But, given I have "Item" entities, with the price I bought it for and the price I sold it for as attributes, how I calculate the total Profit of all Item entities using NSExpressions?

Thank you

Shmidt
  • 16,436
  • 18
  • 88
  • 136
Skyler
  • 2,834
  • 5
  • 22
  • 34

1 Answers1

1

The following expression description computes the price difference for each object:

NSExpression *price1Expr = [NSExpression expressionForKeyPath:@"price1"];
NSExpression *price2Expr = [NSExpression expressionForKeyPath:@"price2"];
NSExpression *profitExpr = [NSExpression
                                    expressionForFunction:@"from:subtract:"
                                    arguments:@[price2Expr, price1Expr]];

NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init];
[expressionDescription setName:@"profit"];
[expressionDescription setExpression:profitExpr];
[expressionDescription setExpressionResultType:NSDoubleAttributeType];

NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Entity"];
[request setPropertiesToFetch:@[expressionDescription]];
[request setResultType:NSDictionaryResultType];
NSArray *profits = [context executeFetchRequest:request error:&error];
NSLog(@"%@", profits);

EDIT: (The question was edited while I was writing the above answer.) Computing the sum of all price differences seems not to be possible with a single fetch request, see for example Chained expressions to perform calculations in Core Data. But you can fetch the array of all price differences, using the above expression description, and calculate the sum using Key-Value coding:

NSArray *profits = result of fetch request
NSNumber *totalProfit = [profits valueForKeyPath:@"@sum.profit"];
NSLog(@"%@", totalProfit);
Community
  • 1
  • 1
Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • Hmmm I get this crash error messsage using the above expression description: Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid keypath (request for aggregate operation on a toOne-only keypath): purchasePrice' – Skyler Jul 11 '13 at 20:14
  • @Skyler: I have tested this now and it worked for me. I have added the complete fetch code to the answer. – Martin R Jul 11 '13 at 20:28
  • @Skyler: Perhaps you can show the definition of your entity and your current code. – Martin R Jul 12 '13 at 07:36
  • as it turns out the issue was passing an array of size greater than one for the method NSFetchRequest setPropertiesToFetch:. I was attempting to perform multiple operations, such as sum all purchase prices, sum all sale prices, etc. If I split the fetch requests' properties to fetch, the application did not crash. Thank you for your help. – Skyler Jul 12 '13 at 23:09