Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sum a CoreData attribute

Tags:

core-data

I've an entity "Expense" with an attribute (float) called "value". I've a table view populated from CoreData with NSFetchedResultsController. I'm trying to show in a label (or table header) the total sum of "values" of all my expenses, but I can't implement a solution after reading Apple Docs and googling different forums. For sure beginner disorientation. Appreciate any indications about the best way to implement this king of operation, or any kind of code that shows similar solution.

like image 957
Diogo Avatar asked Feb 26 '23 07:02

Diogo


1 Answers

first of all. You should use Decimal (the core data name for nsdecimalnumber) and NSDecimalNumber if you want to calculate and store a currency. I implemented the code you need with float. But you should really change it to NSDecimalNumber. Read this to know why you should do this

If you want to add the expense value to the section header it's easy. You basically take the expense of all objects in the section and sum it up.

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
    float expense = 0;
    for (NSManagedObject *object in [sectionInfo objects]) {
        expense += [[object valueForKey:@"expense"] floatValue];
    }
    return [NSString stringWithFormat:@"%@ [Expense: %f]", [sectionInfo name], expense];
}

Even if you don't use sections in your table this will work. But you should change the returned string then.

I think you should be able to understand it. There is also a more general way to do this. I wrote it a little bit more verbose for you. It uses 3 lines instead of 1 in the for-loop but it does exactly the same thing.

float expense = 0;
for (NSManagedObject *object in [self.fetchedResultsController fetchedObjects]) {
    NSNumber *objectExpenseNumber = [object valueForKey:@"expense"];
    float objectExpense = [objectExpenseNumber floatValue];
    expense = expense + objectExpense;
}
NSLog(@"Expense: %f", expense);

Not really much to explain.

edit: this would be the code if you use NSDecimalNumber

NSDecimalNumber *expense = [NSDecimalNumber decimalNumberWithString:@"0"];
for (NSManagedObject *object in [self.fetchedResultsController fetchedObjects]) {
    NSDecimalNumber *objectExpenseNumber = [object valueForKey:@"expense"];
    expense = [expense decimalNumberByAdding:objectExpenseNumber];
}
NSLog(@"Expense: %@", expense);
like image 115
Matthias Bauch Avatar answered Mar 05 '23 01:03

Matthias Bauch