I'm getting values of string in my response to whom i'm storing in an array. Its is storing properly.Now i want to get that values out of my array because later i have to add that in an another string to get their sum. My array looks like this, [0.5,0.5,0.5]. I have to extract all the 0.5 values and add them. I have tried a code it extract the values but in result it shows 0 value. My code is this,
let itemprice = UserDefaults.standard.string(forKey: "itemPrice")
print(itemprice)
let defaults = UserDefaults.standard
let array = defaults.array(forKey: "addonPrice") as? [Int] ?? [Int]()
print(array)
let resultant = array.reduce(0, +)
print(resultant)
let result = itemprice! + String(resultant)
print(result)
i'm trying to add the arrays value to another value with the name itemprice. How can i get out all the values from my array and add them. The values in the array varies different time.
You are getting 0 as a result of let resultant = array.reduce(0, +) because in
let array = defaults.array(forKey: "addonPrice") as? [Int] ?? [Int]()
either the value stored in the defaults is an empty array, or the cast as? [Int] fails.
Considering you claim that the array is supposed to hold values [0.5,0.5,0.5] I assume that it is the latter case. [0.5,0.5,0.5] is an array of Double values, not Int values.
Try to fix it this way:
let array = defaults.array(forKey: "addonPrice") as? [Double] ?? [Double]()
UPDATE
From comments it seems that you are using strings everywhere, so then:
let itemprice = UserDefaults.standard.string(forKey: "itemPrice")
print(itemprice)
let defaults = UserDefaults.standard
// take it as an array of strings
let array = defaults.array(forKey: "addonPrice") as? [String] ?? [String]()
print(array)
// convert strings to Double
let resultant = array.map { Double($0)! }.reduce(0, +)
print(resultant)
let result = Double(itemprice!)! + resultant
print(result)
Although I would strongly recommend you to work with Double from the beginning (both to store it and use it).
Related
I'm trying to make a feature that saves a title and link to a website
This is what I am attempting to store
[0] -> [TITLE, LINK]
[1] -> [TITLE, LINK]
[2] -> [TITLE, LINK]
This is how I am doing it
//Create array
var favoriteProducts = [[String:String]]()
//Add products
let firstArray = [titleName:String(), link:String()]
favoriteProducts.append(firstArray)
//Add to defaults
UserDefaults.standard.set(favoriteProducts, forKey: "favProducts")
The next step is to loop through using ForEach to return the title and link. For debugging I'm trying to use
UserDefaults.standard.array(forKey: "favProducts")![0][0]
Which returns
Value of type 'Any' has no subscripts
However
UserDefaults.standard.array(forKey: "favProducts")![0]
Returns
(website, link)
So my question here is how do I return both the website and link individually and not just the entire subscript?
you can store arrayOfStrings In struct array and can access the vale from struct ,Say example
var favouriteProducts = [[String:Any]]()
var listOfSite = [SiteDetail]()
var firstArray = ["titleName":"String","link":"firstlink"]
var secondArray = ["titleName":"s","link":"s"]
favouriteProducts.append(firstArray)
favouriteProducts.append(secondArray)
UserDefaults.standard.set(favouriteProducts, forKey: "favProducts")
let value = UserDefaults.standard.array(forKey: "favProducts") as? [[String:String]] ?? [[:]]
for values in value{
let siteName = values["titleName"] as? String ?? ""
let link = values["link"] as? String ?? ""
let siteDetail = SiteDetail(website: siteName, link: link)
listOfSite.append(siteDetail)
}
print("listOf \(listOfSite[0].link)")
print("listOf \(listOfSite[0].website)")
//////////////////////////
struct SiteDetail{
var website:String?
var link:String?
}
Here UserDefaults.standard.array returns an array of Any type and you are storing an array of the dictionary. So at the time of retrieve, you need to cast the array element as a dictionary.
Also, you can use the key to get the dictionary value.
let firstElement = (UserDefaults.standard.array(forKey: "favProducts")?[0] as? [String: String])
let title = firstElement?["titleName"]
let link = firstElement?["link"]
I have a problem changing the value of a Dictionary in a Array
var array = (defaults.array(forKey: "Transactions")! as! [Dictionary<String, Any>])
(array.reversed()[index]["Title"] as! String) = titleTextField.text! // Cannot assign to immutable expression of type 'String'
Cannot assign to immutable expression of type 'String'
This is the error I get back
Is there a solution to this problem?
As Joakim points out, array.reversed() returns an immutable array.
Try this:
guard
var array = (defaults.array(forKey: "Transactions")! as? [Dictionary<String, Any>]),
let newText = titletextfield.text,
array[array.count-index]["Title"] = newText
(And then re-save your array to UserDefaults)
One more step will work
if var array = UserDefaults.standard.array(forKey: "Transactions") as? [Dictionary<String, Any>], let valueText = titleTextField.text {
array.reverse()
array[index]["Title"] = valueText
}
I have an array which will always have 4 different autoId's (it grabs 4 at random from a node on firebase) - it is the randomKeyArray shown in the image:
I would like to use the autoIDs from the randomKeyArray to get further information from firebase (users full name and profileImageUrl) set these in separate arrays (names, profileImages and namesWithUrl) so that i can use them later on.
I would like the randomKeyArray[0] to correspond to names[0], profileImages[0], namesWithUrl[0] and the same with 1,2,3 etc.
Right now, the names, profileImages and namesWithUrl arrays are empty and I'm not sure why - would appreciate any help :)
// the arrays are stored outside the viewDidLoad
var randomKeyArray = [String]()
var names = [String]()
var profileImages = [String]()
var namesWithUrl = [String : String]()
//EDIT: this for loop is where i get the random autoId's for the myKeyArray
for _ in 0...3 { //will iterate four times
let count = self.myKeyArray.count //get the number of elements
let randomInt = Int.random(in: 0..<count) //get a random index for the array
let randomUserKey = self.myKeyArray[randomInt]
self.randomKeyArray.append(randomUserKey)
self.myKeyArray.remove(at: randomInt) //remove that object so it's not selected again
}
print(self.myKeyArray)
//for loop is inside a function
for i in 0..<self.randomKeyArray.count {
let thisUserKey = self.randomKeyArray[i]
self.ref.child("users").child(thisUserKey).observeSingleEvent(of: .value, with: { snapshot in
let name = snapshot.childSnapshot(forPath: "fullname").value as! String
let profileImageUrl = snapshot.childSnapshot(forPath: "profileImageUrl").value as! String
self.names.append(name)
self.profileImages.append(profileImageUrl)
self.namesWithUrl[name] = profileImageUrl
//self.currIds.append(self.randomKeyArray)
})
}
Let me know if you need any more info!
EDIT:
I have added the for loop which i get the autoId for the randomKeyArray - I have also tried get the name and profile image when the randomUserKey is called in the first for loop but the arrays still show 0 values
I have created an Array of Dictionaries:
let tempArray = [["id":"1","Name":"ABC"],["id":"2","Name":"qwe"],["id":"3","Name":"rty"],["id":"4","Name":"uio"]]
Now I have to create an array of Name only.
What I have done is this:
var nameArray = [String]()
for dataDict in tempArray {
nameArray.append(dataDict["Name"]!)
}
But is there any other efficient way of doing this.
You can use flatMap (not map) for this, because flatMap can filter out nil values (case when dict doesn't have value for key "Name"), i.e. the names array will be defined as [String] instead of [String?]:
let tempArray = [["id":"1","Name":"ABC"],["id":"2","Name":"qwe"],["id":"3","Name":"rty"],["id":"4","Name":"uio"]]
let names = tempArray.flatMap({ $0["Name"] })
print(names) // ["ABC", "qwe", "rty", "uio"]
Use compactMap as flatMap is deprecated.
let tempArray = [["id":"1","Name":"ABC"],["id":"2","Name":"qwe"],["id":"3","Name":"rty"],["id":"4","Name":"uio"]]
let name = tempArray.compactMap({ $0["Name"]})
print(name)
I am saving data into userDeafults using 2 textfield as String, String but I want to know how to retrieve all the data to display either using loop or function
let save = UserDefaults.standard
let heading = headingText.text
let description = desxriptionTexr.text
save.set(description, forKey: heading!)
To get all keys and corresponding values in UserDefaults, you can use:
for (key, value) in UserDefaults.standard.dictionaryRepresentation() {
print("\(key) = \(value) \n")
}
In swift 3, you can store and retrieve using:
UserDefaults.standard.setValue(token, forKey: "user_auth_token")
print("\(UserDefaults.standard.value(forKey: "user_auth_token")!)")
I think is not a correct way to do.
I suggest you to put your values into a dictionary and set the dictionary into the UserDefaults.
let DictKey = "MyKeyForDictionary"
var userDefaults = UserDefaults.standard
// create your dictionary
let dict: [String : Any] = [
"value1": "Test",
"value2": 2
]
// set the dictionary
userDefaults.set(dict, forKey: DictKey)
// get the dictionary
let dictionary = userDefaults.object(forKey: DictKey) as? [String: Any]
// get value from
let value = dictionary?["value2"]
// iterate on all keys
guard let dictionary = dictionary else {
return
}
for (key, val) in dictionary.enumerated() {
}
If you have multiple Strings, simply save value as array
UserDefaults.standard.set(YourStringArray, forKey: "stringArr")
let arr = UserDefaults.standard.stringArray(forKey: "stringArr")
for s in arr! {
//do stuff
}
Here you are setting the key as heading and the value as description.
You can retrieve the value from userDefaults using UserDefaults.standard.object(forKey:), UserDefaults.standard.string(forKey: ),UserDefaults.standard.value(forKey: ) etc functions.
So its better to save heading and description for 2 different keys may be like
let save = UserDefaults.standard
let heading = headingText.text
let description = desxriptionTexr.text
save.set(description, forKey: "description")
save.set(heading, forKey: "heading")
And you could retrieve like
let description = UserDefaults.standard.string(forKey:"description")
let heading = UserDefaults.standard.string(forKey:"heading")