convert nsmanganedobject to array to find average of array - arrays

My code below fetches a string from core data and finds the sum of the array.I want to know find the average of all of the numbers in the array by dividing the sum by how many items are in the array. I just need someone to build off of this by dividing the amount of numbers by the sum that I have already found.
func performAction() {
let appD = UIApplication.shared.delegate as! AppDelegate
let context = appD.persistentContainer.viewContext
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Data")
request.returnsObjectsAsFaults = false
do {
let result = try context.fetch(request)
var retrievedData = [Double]()
for data in result as! [NSManagedObject] {
if let value = data.value(forKey: "ee") as? String {
retrievedData.append(Double(value) ?? 0)
}
}
let arraySum = retrievedData.reduce(0, +)
print(arraySum)
} catch {
print("Failed")
}
}

Related

Retrieve array of core data element

I want retrieve core data and print the entire array in the log file. Right now my function converts a array to a double and then finds the average of all the numbers All I want to do is print the array of all the elements of the string "ee" in the log file
func performAction() {
let appD = UIApplication.shared.delegate as! AppDelegate
let context = appD.persistentContainer.viewContext
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Data")
request.returnsObjectsAsFaults = false
do {
let result = try context.fetch(request)
var retrievedData = [Double]()
for data in result as! [NSManagedObject] {
if let value = data.value(forKey: "ee") as? String {
retrievedData.append(Double(value) ?? 0)
}
}
let arraySum = retrievedData.reduce(0, +)
print(arraySum/Double(retrievedData.count))
let venus = (arraySum/Double(retrievedData.count))
average.text = String("\(venus)")
} catch {
print("Failed")
}
}

convert nsmanganedobject to array to find sum of array

My code below is trying to take core data from a NSManagedObject append it to an array. The core data element is saved as a string. My code is not compelling. Ideally the code should be able to append code into the array then the array is filled, find the sum of the numbers added together and print them into the viewDidLoad() func.
var itemName : [NSManagedObject] = []
func performAction() {
let appD = UIApplication.shared.delegate as! AppDelegate
let context = appD.persistentContainer.viewContext
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Data")
request.returnsObjectsAsFaults = false
do {
let result = try context.fetch(request)
var retrievedData = [Double]()
for data in result as! [NSManagedObject] {
if let value = data.value(forKey: "ee") as? Double {
retrievedData.append(value)
}
}
let arraySum = retrievedData.reduce(0, +)
print(arraySum)
} catch {
print("Failed")
}
}
I reviewed your code when you will need to change small thing over there. Replace performAction function as per my updated answer.
func performAction() {
let appD = UIApplication.shared.delegate as! AppDelegate
let context = appD.persistentContainer.viewContext
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Data")
request.returnsObjectsAsFaults = false
do {
let result = try context.fetch(request)
var retrievedData = [Double]()
for data in result as! [NSManagedObject] {
if let value = data.value(forKey: "ee") as? String {
retrievedData.append(Double(value) ?? 0)
}
}
let arraySum = retrievedData.reduce(0, +)
print(arraySum)
} catch {
print("Failed")
}
}

How to append new value in index of the null value in NSArray in swift

I wrote an API which returns the username and amount and at what time the transaction was placed. I got the response from the backend as an array of objects and I stored it as NSArray in client side. And I want to attach that response to labels so I converted that NSArray into String and In Database some fields are empty so the response returns the null values whenever the response returns the null values I am getting this error like "Could not cast the value of NSNUll to NSString". What I thought is replace the null value in that array with string. I tried so much but it always shows the same error how to resolve that problem. This is my code :
let response = JSON as! NSDictionary
//example if there is an id
let deyaPaybalance = response.object(forKey: "Details")
print(deyaPaybalance!)
let Amount1:[Double] = (response.object(forKey: "Amount")) as! [Double]
print("Amount is",Amount1)
for ele:Double in Amount1 {
self.amo += [String(ele)]
}
print("amount is in string",self.amo)
let time = response.object(forKey: "Time") as! NSArray
print("time is", time)
let id = response.object(forKey: "TransactionID")
print("id is",id!)
let name:NSArray = response.object(forKey: "RName") as!NSArray
print("name is",name)
// let len = name.count
for (object) in name.enumerated() {
if let i = name.index(of: "null") {
print("hey it's nnull")
//name.index(of: "null")
}
else {
print("hello")
}
}
print("name",name)
// It is used to get the date from the time tsamp
for element in time {
let ele = element
let formatter = ISO8601DateFormatter()
//print("date is",date1!)
formatter.formatOptions = [.withFullDate,
.withTime,
.withDashSeparatorInDate,
.withColonSeparatorInTime]
self.date2 = formatter.date(from: ele as! String)!
self.anotherFormatter.dateFormat = "MMM dd yyyy, h:mm a" // It is used to to show the date in th form of month year and time
self.anotherFormatter.string(from: self.date2)
let b = self.anotherFormatter.string(from: self.date2)
let final = b.replacingOccurrences(of: ",", with: " ")
let trimmedString = final.trimmingCharacters(in: .whitespaces)
self.dt += [trimmedString] // it is stored the final date and time
print("final tim is",trimmedString)
}
// End of the for loop
print(self.dt)
let contactViewController = self.storyboard?.instantiateViewController(withIdentifier: "TransactionDetails")as! TransactionDetails
contactViewController.method = deyaPaybalance as! [String]
contactViewController.amount = self.amo
contactViewController.timestamp = self.dt
contactViewController.transactionid = id as! [String]
contactViewController.name = name as! [String]// I am getting error here.
self.navigationController?.pushViewController(contactViewController, animated: true)
self.dismiss(animated: false, completion: nil)
UIApplication.shared.endIgnoringInteractionEvents()
You need to use like this to handle null in swift.
if let arr_name = name as? [String]{
contactViewController.name = arr_name
}else{
contactViewController.name = []
}
For replacing nil value in [String]
var name = ["a",nil,"3"]
if let nil_index = name.index(of: nil){
name[nil_index] = "empty"
}
print(name as! [String]) // Output is ["a", "empty", "3"]

Swift - Appending values to Array after Rounding values

I'm running a for loop to get values returned from JSON. I'm getting the latitude values more specifically. I'm rounding the values using dblLat = (dblLat * 100).rounded() / 100
When appending the values to a new Array, only the first element is appended correctly as rounded, thereafter each new element is appended as a double with 15 decimal places:
do {
let json = try JSONSerialization.jsonObject(with: data, options: [])
//print(json)
var latArray = [Double]()
guard let array = json as? [Any] else { return }
for user in array {
guard let userDict = user as? [String: Any] else { return }
guard let userID = userDict["id"] as? Int else { print("No Int Value Present"); return }
guard let name = userDict["name"] as? String else { return }
print(name)
guard let company = userDict["company"] as? [String : String] else { return }
print(company)
guard let companyName = company["name"] as? String else { return }
print(companyName)
guard let address = userDict["address"] as? [String : Any] else { return }
guard let geo = address["geo"] as? [String : String] else { return }
print(geo)
guard let lat = geo["lat"] as? String else { return }
guard var dblLat = Double(lat) else { return }
dblLat = (dblLat * 100).rounded() / 100
print(dblLat)
latArray.append(dblLat)
print(latArray)
//print(lat)
print(userID)
}
} catch {
print(error)
}
Printing the array:
[-37.32, -43.950000000000003, -68.609999999999999, 29.460000000000001, -31.809999999999999, -71.420000000000002, 24.890000000000001, -14.4, 24.649999999999999, -38.240000000000002]
The Binary representation of some numbers is just infinite. Have a look here.
You could use a NumberFormatter to get strings with two decimal places
let array = [-37.32, -68.609999999999999, 29.460000000000001, -31.809999999999999, -71.420000000000002, 24.890000000000001, -14.4, 24.649999999999999, -38.240000000000002]
let formatter = NumberFormatter()
formatter.numberStyle = .decimal
formatter.minimumFractionDigits = 2
formatter.maximumFractionDigits = 2
let roundedStringsArray = array.map {formatter.string(from: NSNumber(floatLiteral: $0))!}
print(roundedStringsArray)

Look through all records for a specific attribute and see the highest value

Ok, so I have an app that is designed for roleplaying. I have a guide that guides the user to creating the character. So the first thing the user has to do is put the character number. So I want it to search all the records for the attribute I have called characternumber and see what the largest number is.
Example: Lets say I have 5 characters. with character numbers 1,2,3,4,5. I want to cycle through all the records and see that 5 is the biggest number than automatically place a 6 in the character number text field.
This is what I have so far:
#IBOutlet var societyNumberTxt: UITextField!
#IBOutlet var characterNumberTxt: UITextField!
let managedObjectContext = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
var characters: [NSManagedObject] = []
var societyNum: [NSManagedObject] = []
var charNum: [String] = []
override func viewDidLoad()
{
super.viewDidLoad()
//1
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
return
}
let managedContext = appDelegate.persistentContainer.viewContext
//2
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "Characters")
//3
do {
societyNum = try managedContext.fetch(fetchRequest)
let entityDescription = NSEntityDescription.entity(forEntityName: "Characters", in: managedObjectContext)
let request: NSFetchRequest<Characters> = Characters.fetchRequest()
request.entity = entityDescription
var results = try managedObjectContext.fetch(request as! NSFetchRequest<NSFetchRequestResult>)
if societyNum.count > 0
{
let match = results[0] as! NSManagedObject
societyNumberTxt.text = (match.value(forKey: "societynumber") as? String)!
print(match)
if (match.value(forKey: "characternumber") != nil)
{
self.charNum = match.value(forKey: "characternumber") as! [String]
print(self.charNum)
}
else
{
print("empty array")
characterNumberTxt.text = "1"
}
}
else
{
societyNumberTxt.placeholder = "Society # not set"
}
} catch let error as NSError {
print("Could not fetch. \(error), \(error.userInfo)")
}
}
I am not sure how to cycle through every record and check the attribute and place in the array. I have tried something like this:
var i = 0
for i in results
{
var match = results[i] as? NSManagedObject
charNum[i] = match
}
I get the error:
cannot subscript a value of type '[Any]' with an index of type 'Any'
Now to test my code for the if statement:
if (match.value(forKey: "characternumber") != nil)
{
self.charNum = match.value(forKey: "characternumber") as! [String]
print(self.charNum)
}
It returned and error:
Could not cast value of type 'NSTaggedPointerString' (0x108578d10) to 'NSArray' (0x108578dd8).
Am I even on the right past?
Adjust your fetch request with a SortDescriptor instead of finding the highest characterNumber manually:
...
//2
// get all characters ...
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "Characters")
// ... sorted by characternumber in acending order
let sortDescriptor = NSSortDescriptor(key: "characternumber", ascending: true)
let sortDescriptors = [sortDescriptor]
fetchRequest.sortDescriptors = sortDescriptors
//3
do {
let characters = try managedContext.fetch(fetchRequest) as! [Characters]
if let highestCharacterNumber = characters.last?.characternumber {
characterNumberTxt.text = String(highestCharacterNumber + 1) // assuming characternumber is of type Int
} else {
characterNumberTxt.text = "1"
}
} ...

Resources