Swift3 loop dictionary to add value - swift

I m new to programming I just playing around in playground, I am trying to loop in a dictionary to do some calculation and add them into new dictionary however, I can only add one dictionary value back. I am not sure why. Can anymore tell me and point out the point?
var name:String?
var popDict: [String: Array<Double>]?
var FinalDict: [String: Array<Double>]?
var mean: Double?
var elementSideArr: Array<Double>?
var nameArray = ["Olivia": [1,2,2,2,1,2,1,0.0001,0,1,2], "Amber": [52,52,65,66,57,63,62,0.0001,0,0,0]]
var doubleArr = [Double]()
for (key, value) in nameArray{
let thisValue = value
let arrayS = thisValue.prefix(7)
let slice = arrayS[0...6]
let popSideArr = Array(slice)
let average: Double = (popSideArr as NSArray).value(forKeyPath: "#avg.self") as! Double
mean = average
let thatValue = value
let arraySS = thatValue.suffix(3)
let sslice = arraySS[8...10]
elementSideArr = Array(sslice)
elementSideArr?.insert(average, at: 0)
let dict = ["\(key)": elementSideArr!]
for (key,value) in dict{
popDict = dict
}
}
print(popDict!)
["Olivia": [1.5714285714285714, 0.0, 1.0, 2.0]] // It is the only output but it should be 2 items.

Problem is in your inner for loop you are initializing whole new dictionary to popDict also you don't need for loop if you are having single key and value pair with your dictionary.
Replace line of codes:
let dict = ["\(key)": elementSideArr!]
for (key,value) in dict{
popDict = dict
}
With:
popDict["\(key)"] = elementSideArr!
Note: No need to cast swift array to NSArray to calculate average you can simply use reduce to get total and then divide the total with array count.
let array = popSideArr as? [Int] ?? []
let res = Double(array.reduce(0, +)) / Double(popSideArr.count)

Related

Firestore get array data at index 0

Below I have some data in firestore.
I have a an array in the _geoloc field. Each of those indexes have latitude and longitude coordinates. So using SWIFT I want to be able to only get the lat and lng coordinates at index 0 and pass them to individually to a string. I have been researching for days and I am stuck. I have tried to create a new array of strings or an AnyObject array and I just get stuck with retrieving the data I need at index 0, and passing only those 2 lat/lng coordinates to string values. I have several failed snippets of code I could post.
Here is a snippet of what I was attempting to do: (I am really new to firebase so the code is a bit ugly as I am just trying to figure this out)
Firestore.firestore().collection("users").document("626").getDocument { (document, error) in
if let document = document {
// let geo_array = document["_geoloc"]
var yourArray = [String]()
// let geo_location = [geo_array] as [AnyObject]
let array: [Any] = document["_geoloc"] as! [Any]
let tmpArray = array.map({ return String(describing: $0)})
let string = tmpArray.joined(separator: ",")
yourArray.append(string)
print(yourArray[0])
You just need to cast your object from Any to an array of dictionaries and get the first property:
Firestore.firestore().collection("users").document("626").getDocument { document, error in
if let document = document {
var yourArray: [String] = []
if let location = (document["_geoloc"] as? [[String:Double]])?.first,
let latitude = location["lat"],
let longitude = location["lon"] {
let coordinate2d = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
yourArray.append("Latitude: \(location.latitude), Longitude: \(location.Longitude)")
}
}
}
Maybe first declare this:
var firstPositionValues = [AnyObject]()
Then get it like this:
let db = Firestore.firestore().collection("users").document("626")
db.getDocument { (document, error) in
if let document = document {
let geo_location = document["_geoloc"] as [AnyObject] // <- this is all of them in the document
var initialValues = geo_location[0] // <- here are your lat and lng at position 0
self.firstPositionValues = initialValues
}
Hope I understood correctly good luck.

Using Swift pull data from firebase

This is how my Firebase looks like
Firebase ScreenShot
This is my code
override func viewDidLoad() {
var sum = 0
var counter = 0
super.viewDidLoad()
ref = Database.database().reference()
ref.child("WaterAdded").observe(.childAdded, with: { (snapshot) in
if let totalwateradded = snapshot.value as? [Int]{
while counter < (totalwateradded.count) {
var newValue = totalwateradded[counter]
sum += newValue
}
self.totalAdded.text = "\(sum)"
}
})
}
I want to grab all the number in Firebase and display the sum. But it display nothing.
You cannot directly cast snapshot.value to [Int], instead if you want to get all objects in your node you should use
let ref = Database.database().reference()
ref.child("WaterAdded").observe(.childAdded, with: { (snapshot) in
if let water = snapshot.value as? String{
guard let waterAmount = Int(water) else{return}
sum += waterAmount
}
})
that while loop is not needed as this will give you all the values in the database.
Edit
In the database you can use Strings and Ints to store numbers. You store them as Strings. If you load them in Swift you have to conditionally cast the value to String (as? String). The problem, however is that you can not do any arithmetic operations on strings so using the Int(water) statement you can convert it to Int. This operation can give an integer from a string if it contains a number, but it can also fail (e.g. Int("two")) and therefore we use guard let to make sure we only proceed to the next line if it can successfully convert to an Int. Afterwards we just add the int value to sum and done.
try...
if let snap = snapshot.value as? Dictionary [Sting: Any], let totalWaterAdded =
snap["\(yourDictionaryKey)"] as? Int{
//enter your code...
}
Here's the answer that reads the node, sums the values and print it to console.
let ref = self.ref.child("WaterAdded")
ref.observeSingleEvent(of: .value, with: { snapshot in
var x = 0
for child in snapshot.children {
let val = (child as! DataSnapshot).value as! Int
x = x + val
}
print("sum: \(x)")
})
We're using observeSingleEvent of .value in this case as there's really no reason for firebase to iterate over each child when we can do it a lot faster in code. Also, we don't need to be notified of childAdded events.
Tossing a guard statement in the mix may be a good idea but as long as you are sure the values will only be Int's, it's good to go as is.
Tested with the following structure
WaterAdded
a: 0
b: 1
c: 2
d: 3
and the output is
6

Get the value of a Swift variable from a constructed name

I am stuck at a problem which i am trying to figure out in Swift 4.
Let say, i have the below variables
let var1 = "One"
let var2 = "Two"
let var3 = "Three"
var counter = 1
// Loop Start
let currentVariable = "var" + "\(counter)"
//Fetch the value of variable stored under currentVariable
counter += 1
//Loop end
I am trying to get the value based on variable name stored under currentVariable.
You can set up dictionary, replacing your variable names with keys.
let letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
var myDictionary:[String:String] = ["var1":"One", "var2":"Two", "varA":"A", "varB":"B"] // note, both sides can be different types than String
for x in 0...9 {
let myKey = "var" + String(x)
printValue(myKey)
}
for x in letters.characters {
let myKey = "var" + String(x)
printValue(myKey)
}
The simple function:
func printValue(_ key:String) {
let myValue = myDictionary[key]
if myValue != nil {
print(myValue)
}
}
I'm pretty sure you can make things a bit more elegant, but you get the idea. Also, keep in mind that a Dictionary is "unordered", as opposed to an array.
Use an array
let myArray = ["one", "two", "three"];
var counter = 1;
print(myArray[counter]);

swift 2 collection for sorting a key value pair by value

I am using swift 2 to access microsoft's emotion api. This returns a json object that is placed into an NSArray then dictionary like so:
`let info : NSArray = (json.valueForKey("scores") as? NSArray)!
let anger: Float? = info[0].valueForKey("anger") as? Float
let contempt: Float? = info[0].valueForKey("contempt") as? Float
let disgust: Float? = info[0].valueForKey("disgust") as? Float
let fear: Float? = info[0].valueForKey("fear") as? Float
let happiness: Float? = info[0].valueForKey("happiness") as? Float
let neutral: Float? = info[0].valueForKey("neutral") as? Float
let sadness: Float? = info[0].valueForKey("sadness") as? Float
let surprise: Float? = info[0].valueForKey("surprise") as? Float
emotions.append(anger!)
emotions.append(contempt!)
emotions.append(disgust!)
emotions.append(fear!)
emotions.append(happiness!)
emotions.append(neutral!)
emotions.append(sadness!)
emotions.append(surprise!)
let dictionary = [
"anger" : [emotions[0]],
"contempt" : [emotions[1]],
"disgust" : [emotions[2]],
"fear" : [emotions[3]],
"happiness" : [emotions[4]],
"neutral" : [emotions[5]],
"sadness" : [emotions[6]],
"surprise" : [emotions[7]]
]
i need to get the values sorted because the largest float will determine the emotion, so i have to keep the key to know what the mapped emotion is. What would be the best collection to do this, i already know a dictionary is not meant to be sorted.
This code extracts the first dictionary of the JSON scores array like you did but returns if there is nothing there. Then it (1) removes all elements except the emotion keys that you are interested in, (2) converts the remaining emotion values to Float, and (3) returns a tuple of the largest valued element. Ignore the tuple's second value (emotion score).
let keys = ["anger", "contempt", "disgust", "fear", "happiness", "neutral", "sadness", "surprise"]
guard let info = (json.valueForKey("scores") as? Array).first else { return }
let (emotion, _) = info
.filter { (k, _) in keys.contains(k) }
.map { (k, v) in (k, Float(v)) }
.maxElement()
You can now use the value of emotion in your UI as needed.

How to Insert values in Dictionary in swift

I first declare dictionary
let storeSentenceOrdering = [String, Int ]();
then I want to insert value in it but I am getting an error:
- We can do this in following way
var carDictionary: [String:Int] = [:]
// Below is a subscript way of adding or updating value to the Dictionary, if the key is not present then the key is inserted with the assigned value else its updated with the new value
carDictionary["Ford"] = 345000
carDictionary["Hyundai"] = 546788
print(carDictionary)
- We can also use update to add value to the existing Dictionary
carDictionary.updateValue(234500,forKey:("Wolkswagen"))
- Dictionary can be initialized in one the following ways
var carDictionaryOne: [String:Int] = [:]
var carDictionaryTwo: [String:Int] = ()
var carDictionaryThree = ["Ford":12345, "Audi":57689]
try it...
var dict : NSDictionary!
dict = [1:"Hello", 2:"How", 3:"Are", 4:"You"]
let value = dict[1]
print(value!) // Print First Element
//print all element
for(var i=1; i<5; i++)
{
let value = dict[i]
print(value)
}