Core Data sum of all instances attribute
Having a managedObjectContext:
NSManagedObjectContext *managedObjectContext = ...
We create a fetch request with return type dictionary:
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass([Movement class])];
fetchRequest.resultType = NSDictionaryResultType;
Then we create an expression description to calculate the sum:
NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init];
expressionDescription.name = @"sumOfAmounts";
expressionDescription.expression = [NSExpression expressionForKeyPath:@"@sum.amount"];
expressionDescription.expressionResultType = NSDecimalAttributeType;
Set the request properties to fetch:
fetchRequest.propertiesToFetch = @[expressionDescription];
We could also set a predicate if we want.
And last we execute the request and get an array containing a dictionary with one key(@"sumOfAmounts") and its value is a NSNumber with the sum of amounts.
NSError *error = nil;
NSArray *result = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
if (result == nil)
{
NSLog(@"Error: %@", error);
}
else
{
NSNumber *sumOfAmounts = [[result objectAtIndex:0] objectForKey:@"sumOfAmounts"];
}
Cheers
How to sum filtered Core Data in SwiftUI?
I have found similar problem in this question:
Sum of (double) fetch request field
I have modified the code a little and came up with this solution:
import SwiftUI
import CoreData
struct DashboardView: View {
@Environment(\.managedObjectContext) var managedObjectContext
// FetchRequest with predicate set to "after now"
@FetchRequest(entity: NPTransaction.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \NPTransaction.value, ascending: false)], predicate: NSPredicate(format: "date > %@", Date() as NSDate)) var fetchRequest: FetchedResults<NPTransaction>
// sum results using reduce
var sum: Int64 {
fetchRequest.reduce(0) { $0 + $1.value }
}
var body: some View {
NavigationView {
VStack(alignment: .leading) {
HStack {
VStack(alignment: .leading) {
Text("sum")
Text("\(sum)")
.font(.largeTitle)
}
Spacer()
}
.padding()
Spacer()
}.navigationBarTitle("Title")
}
}
}
struct DashboardView_Previews: PreviewProvider {
static var previews: some View {
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
return DashboardView().environment(\.managedObjectContext, context)
}
}
How to get Total Sum of all entries in a Core Data attribute?
You can use NSExpressionDescription
to get the sum directly via fetch request (without fetching the managed objects themselves, which can be inefficient if you have many of them).
Remember to set NSDictionaryResultType
for the fetch request (I got EXC_BAD_ACCESS if I didn't do that).
NSExpression *keyExpression = [NSExpression expressionForKeyPath:@"numberOfSeconds"];
NSExpression *sumExpression = [NSExpression expressionForFunction:@"sum:" arguments:@[keyExpression]];
NSExpressionDescription *sumDescription = [[NSExpressionDescription alloc] init];
sumDescription.name = @"sumOfSeconds";
sumDescription.expression = sumExpression;
[sumDescription setExpressionResultType:NSDecimalAttributeType];
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Entity"];
request.resultType = NSDictionaryResultType;
[request setPropertiesToFetch:@[sumDescription]];
NSError *error = nil;
NSManagedObjectContext *context = ... //get the context somehow
NSArray* fetchResult = [context executeFetchRequest:request error:&error];
NSNumber *sum = fetchResult.firstObject[sumDescription.name]; //this is your sum
Reference: Apple Core Data guide
Sum of an attribute from all objects in a core data entity
Your raw transactions is set of transactions managedObject.Create a variable called count and run a for loop and add money.
var count = 0
for trans in member.transtion {
count = trans.money + count
}
Sum of values from Core Data entity for a different Attribute value
You could do it all in the query using group by and a dictionary result. Simpler perhaps is to just collapse the n^^2 algorithm used to compute the duration into:
let result = records.reduce(into: [:]) { acc, record in
acc[record.title, default:0.0] += record.duration
}
That will build a dictionary of title to total duration in close to order n time.
If you really want two arrays, you can add:
.reduce(into: ([String](), [Double]())) {
$0.0.append($1.key)
$0.1.append($1.value)
}
Core Data, Get Sum Of Certain Boolean Value Attribute
Since your property is a boolean, you can make it a lot simpler than the methods described in that answer. Use a predicate to match the value of passed
and then get the count of the result instead of the fetched objects. Something like:
NSFetchRequest<Event *> *fetchRequest = MyEntity.fetchRequest;
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"passed = true"];
NSError *error = nil;
NSUInteger count = [self.managedObjectContext countForFetchRequest:fetchRequest error:&error];
Then count
has the number of instances where passed
is true
.
How to Sum in Core Data
no matter what it works as this:
let fetchRequest = NSFetchRequest<NSDictionary>(entityName:"Trade")
fetchRequest.predicate = NSPredicate(format: "year = %d and month = %d",year,month)
// sort by day
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "day", ascending: true)]
//group by day for sum
fetchRequest.propertiesToGroupBy = ["day"]
var expressionDescriptions = [AnyObject]()
var expD = NSExpressionDescription()
// select day
expD.name = "day"
expD.expression = NSExpression(forKeyPath: "day")
expD.expressionResultType = .integer16AttributeType
expressionDescriptions.append(expD)
//select @sum.amount as dailysum
expD = NSExpressionDescription()
expD.name = "total"
expD.expression = NSExpression(forFunction: "sum:", arguments: [NSExpression(forKeyPath: "amount")])
expD.expressionResultType = .integer16AttributeType
expressionDescriptions.append(expD)
fetchRequest.propertiesToFetch = expressionDescriptions
fetchRequest.resultType = .dictionaryResultType
var result = [Int:String]()
do {
let fetchResult = try viewContext.fetch(fetchRequest)
for item in fetchResult {
result[item.value(forKey: "day") as! Int] = String(describing: item.value(forKey: "total") as! Int)}
} catch {
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
return result
SwiftUI: Group and Sum by Core Data Attribute
You should not have brackets around the i in [i] in. Brackets like that capture a value, but you don't have a variable to capture -- you're just getting a parameter for the closure.
ForEach(group(items), id: \.self) { i in
On your next line, you're dealing with a multidimensional array. You can't access a property directly, but you could map
first:
Text("\(i.map(\.cost).reduce(0,+))")
You could also structure this slightly differently and remove the map by doing:
i.reduce(0,{ $0 + $1.cost })
Related Topics
Mapkit Annotations Disappearing
Multiple Localized .Strings Files in iOS App Bundle
Allow "Auto Lock" While Video Is Being Played
In-App Purchase Sandbox Environment Loop
Autolayout: Origin and Size Should Change According to Width and Height Factor
Swiftui Foreach Index Out of Range Error When Removing Row
Preventing Avcapturevideopreviewlayer from Rotating, But Allow UI Layer to Rotate with Orientation
Why Was Uitextfield's Text Property Changed to an Optional in Swift 2
How to Sign Out of Apple After Being Authenticated
How to Capture Taps Ignored by Wkwebview
Didbegincontact Is Being Called Multiple Times for the Same Skphysicsbody
Unrecognized Error in Mapview (Ios)
Programmatically Determine Current Target (Run or Test) in iOS Project
Convert Arabic String to English Number in Swift
Mpmediaitemartwork Is Null While Cover Is Available in Itunes