NEW: My new book Pro SwiftUI is out now – level up your SwiftUI skills today! >>

Data from multiple entities into array for math ops

Forums > Swift

Hello,

I have multiple entities of a type which I would like to extract all of the elements of a certain field into an array and then perform a math operation onto it. An example is if I had multiple homes each with a field 'price' and I would like to determine the max price. I expect either a fetch or or calling allObjects and converting the target field to an array operation followed by calling .max() on the array. Thank you

   

You can use NSExpression to create a fetch request for the following functions: sum, count, min, max, and average.

Some sample code (from Group by, Count and Sum in CoreData | Cocoanetics):

let keypathExp1 = NSExpression(forKeyPath: "col")
let expression = NSExpression(forFunction: "sum:", arguments: [keypathExp1])
let sumDesc = NSExpressionDescription()
sumDesc.expression = expression
sumDesc.name = "sum"
sumDesc.expressionResultType = .integer64AttributeType

let request = NSFetchRequest(entityName: "Record")
request.returnsObjectsAsFaults = false
request.propertiesToFetch = [sumDesc]
request.resultType = .dictionaryResultType

Another example, from objc.io's book Core Data (pp82-83):

let request = NSFetchRequest<NSManagedObject>(entityName: "Employee") 
request.resultType = .dictionaryResultType

let salaryExp = NSExpressionDescription() 
salaryExp.expressionResultType = .doubleAttributeType
salaryExp.expression = NSExpression(forFunction: "average:", arguments: [NSExpression(forKeyPath: "salary")])
salaryExp.name = "avgSalary" 

request.propertiesToGroupBy = ["type"]
request.propertiesToFetch = ["type", salaryExp] 
_ = try! context.fetch(request)

Hopefully these can get you started. And maybe someone else on here has an example from their own code they can share.

   

thanks for posting, I believe the first example is exactly what I am looking for. Will try it out

   

hmm, I must be missing something.

let's take a simple department, employee example, in which I would like to find the sum of employee computers. The following expected code does not work for me. What am I doing wrong? results is always invalid. Thank you


let keypathExp1 = NSExpression(forKeyPath: "computer")
let expression = NSExpression(forFunction: "sum:", arguments: [keypathExp1])
let sumDesc = NSExpressionDescription()
sumDesc.expression = expression
sumDesc.name = "sum"
sumDesc.expressionResultType = .integer64AttributeType

let request = NSFetchRequest(entityName: "department")
request.returnsObjectsAsFaults = false
request.propertiesToFetch = [sumDesc]
request.resultType = .dictionaryResultType

let fetch: NSFetchRequest = department.fetchRequest()
do{
    let results = try? fetch.execute()
    print(results ?? "invalid?")  // results is now an array
}
catch {
   NSLog("Error fetching entity: %@", error.localizedDescription)
}

Edit: put source in code block for clean formatting

   

First things first...

When posting code to these forums, place three backticks ``` on the line before your code and three backticks ``` on the line after your code so that it will be formatted properly. You can also highlight an entire code block and click the </> button on the toolbar to wrap the block for you.

This makes it far easier to read and also makes it easier for other posters to copy/paste the code in order to test solutions and such.

Doing this will ensure that you end up with something like this:

let keypathExp1 = NSExpression(forKeyPath: "computer") 
let expression = NSExpression(forFunction: "sum:", arguments: [keypathExp1]) 
let sumDesc = NSExpressionDescription() 
sumDesc.expression = expression 
sumDesc.name = "sum" 
sumDesc.expressionResultType = .integer64AttributeType

let request = NSFetchRequest(entityName: "department") 
request.returnsObjectsAsFaults = false 
request.propertiesToFetch = [sumDesc] 
request.resultType = .dictionaryResultType

let fetch: NSFetchRequest = department.fetchRequest() 
do{ 
    let results = try? fetch.execute() 
    print(results ?? "invalid?") // results is now an array 
} catch { 
    NSLog("Error fetching entity: %@", error.localizedDescription) 
}

instead of this:

let keypathExp1 = NSExpression(forKeyPath: "computer") let expression = NSExpression(forFunction: "sum:", arguments: [keypathExp1]) let sumDesc = NSExpressionDescription() sumDesc.expression = expression sumDesc.name = "sum" sumDesc.expressionResultType = .integer64AttributeType

let request = NSFetchRequest(entityName: "department") request.returnsObjectsAsFaults = false request.propertiesToFetch = [sumDesc] request.resultType = .dictionaryResultType

let fetch: NSFetchRequest = department.fetchRequest() do{ let results = try? fetch.execute() print(results ?? "invalid?") // results is now an array } catch { NSLog("Error fetching entity: %@", error.localizedDescription) }

1      

bump

   

Sorry it's taken me so long to respond; real life got in the way for a while.

Anyway, check out this simple sample project I uploaded to github: roosterboy/CoreDataFunctions

Hopefully, this will give you a good idea how to do what you are looking to do.

1      

thanks so much for the reply @roosterboy. Taking a look at this solution now. Will reply back

   

Hacking with Swift is sponsored by Play

SPONSORED Play is the first native iOS design tool created for designers and engineers. You can install Play for iOS and iPad today and sign up to check out the Beta of our macOS app with SwiftUI code export. We're also hiring engineers!

Click to learn more about Play!

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.