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'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).
I am newly to Swift programming. I am developing an app where I have an array of Objects that I need to save it into one Dictionary, means for Dictionary 'Array of Objects' should be my Value and 'ID' should be my Key.
Here 2 elements contains in my Array, how can I save and retrieve from Dictionary using any unique Key. Please suggest me. Thank you!
You can do it by
var myDict = Dictionary<String, Any>()
myDict = ["myKey": myArrayObjectName as! VideoRangeInfo]
Now you can access you array by use "myKey" of dictionary like below,
print("My array = \(myDict["myKey"] as! VideoRangeInfo)")
UPDATED: I think your array is objective c NSMutableArray not swift Array so
var myDic = NSMutableDictionary()
myDic.setObject(myArrayObjectName, forKey: "myKey")
And
print("My array = \(myDic.object(forKey: "MyKey") as! VideoRangeInfo)")
One simple approach is:
struct VideoRangeInfo {
var name: String
}
var arrayVideoRange = [
VideoRangeInfo(name: "Name1"),
VideoRangeInfo(name: "Name2"),
VideoRangeInfo(name: "Name3")
]
var dictionary = [String: VideoRangeInfo]()
for obj in arrayVideoRange {
dictionary.updateValue(obj, forKey: obj.name)
}
print(dictionary["Name1"]!)
print(dictionary["Name2"]!)
print(dictionary["Name3"]!)
Saving
var dictionary = Int:String
dictionary.updateValue(value: self.arrangeVideoInfo[0]!, forKey: 1)
dictionary.updateValue(value: self.arrangeVideoInfo[0]!, forKey: 2)
Getting
let value1 = dictionary[1] as! VideoRangeInfo
let value2 = dictionary[2] as! VideoRangeInfo
How can I cast an array initially declared as container for Any object to an array of Strings (or any other object)?
Example :
var array: [Any] = []
.
.
.
array = strings // strings is an array of Strings
I receive an error : "Cannot assign value of type Strings to type Any"
How can I do?
You can't change the type of a variable once it has been declared, so you have to create another one, for example by safely mapping Any items to String with flatMap:
var oldArray: [Any] = []
var newArray: [String] = oldArray.flatMap { String($0) }
Updated to Swift 5
var arrayOfAny: [Any] = []
var arrayOfStrings: [String] = arrayOfAny.compactMap { String(describing: $0) }
You can use this synatic sugar grammar. Still one line of code :)
var arr: [Any] = []
var strs = [String]()
arr = strs.map {$0 as! [String]}
Trying to fill an array with strings from the keys in a dictionary in swift.
var componentArray: [String]
let dict = NSDictionary(contentsOfFile: NSBundle.mainBundle().pathForResource("Components", ofType: "plist")!)
componentArray = dict.allKeys
This returns an error of: 'AnyObject' not identical to string
Also tried
componentArray = dict.allKeys as String
but get: 'String' is not convertible to [String]
Swift 3 & Swift 4
componentArray = Array(dict.keys) // for Dictionary
componentArray = dict.allKeys // for NSDictionary
With Swift 3, Dictionary has a keys property. keys has the following declaration:
var keys: LazyMapCollection<Dictionary<Key, Value>, Key> { get }
A collection containing just the keys of the dictionary.
Note that LazyMapCollection that can easily be mapped to an Array with Array's init(_:) initializer.
From NSDictionary to [String]
The following iOS AppDelegate class snippet shows how to get an array of strings ([String]) using keys property from a NSDictionary:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let string = Bundle.main.path(forResource: "Components", ofType: "plist")!
if let dict = NSDictionary(contentsOfFile: string) as? [String : Int] {
let lazyMapCollection = dict.keys
let componentArray = Array(lazyMapCollection)
print(componentArray)
// prints: ["Car", "Boat"]
}
return true
}
From [String: Int] to [String]
In a more general way, the following Playground code shows how to get an array of strings ([String]) using keys property from a dictionary with string keys and integer values ([String: Int]):
let dictionary = ["Gabrielle": 49, "Bree": 32, "Susan": 12, "Lynette": 7]
let lazyMapCollection = dictionary.keys
let stringArray = Array(lazyMapCollection)
print(stringArray)
// prints: ["Bree", "Susan", "Lynette", "Gabrielle"]
From [Int: String] to [String]
The following Playground code shows how to get an array of strings ([String]) using keys property from a dictionary with integer keys and string values ([Int: String]):
let dictionary = [49: "Gabrielle", 32: "Bree", 12: "Susan", 7: "Lynette"]
let lazyMapCollection = dictionary.keys
let stringArray = Array(lazyMapCollection.map { String($0) })
// let stringArray = Array(lazyMapCollection).map { String($0) } // also works
print(stringArray)
// prints: ["32", "12", "7", "49"]
Array from dictionary keys in Swift
componentArray = [String] (dict.keys)
You can use dictionary.map like this:
let myKeys: [String] = myDictionary.map{String($0.key) }
The explanation:
Map iterates through the myDictionary and accepts each key and value pair as $0. From here you can get $0.key or $0.value. Inside the trailing closure {}, you can transform each element and return that element. Since you want $0 and you want it as a string then you convert using String($0.key). You collect the transformed elements to an array of strings.
dict.allKeys is not a String. It is a [String], exactly as the error message tells you (assuming, of course, that the keys are all strings; this is exactly what you are asserting when you say that).
So, either start by typing componentArray as [AnyObject], because that is how it is typed in the Cocoa API, or else, if you cast dict.allKeys, cast it to [String], because that is how you have typed componentArray.
extension Array {
public func toDictionary<Key: Hashable>(with selectKey: (Element) -> Key) -> [Key:Element] {
var dict = [Key:Element]()
for element in self {
dict[selectKey(element)] = element
}
return dict
}
}
dict.keys.sorted()
that gives [String]
https://developer.apple.com/documentation/swift/array/2945003-sorted
From the official Array Apple documentation:
init(_:) - Creates an array containing the elements of a sequence.
Declaration
Array.init<S>(_ s: S) where Element == S.Element, S : Sequence
Parameters
s - The sequence of elements to turn into an array.
Discussion
You can use this initializer to create an array from any other type that conforms to the Sequence protocol...You can also use this initializer to convert a complex sequence or collection type back to an array. For example, the keys property of a dictionary isn’t an array with its own storage, it’s a collection that maps its elements from the dictionary only when they’re accessed, saving the time and space needed to allocate an array. If you need to pass those keys to a method that takes an array, however, use this initializer to convert that list from its type of LazyMapCollection<Dictionary<String, Int>, Int> to a simple [String].
func cacheImagesWithNames(names: [String]) {
// custom image loading and caching
}
let namedHues: [String: Int] = ["Vermillion": 18, "Magenta": 302,
"Gold": 50, "Cerise": 320]
let colorNames = Array(namedHues.keys)
cacheImagesWithNames(colorNames)
print(colorNames)
// Prints "["Gold", "Cerise", "Magenta", "Vermillion"]"
Swift 5
var dict = ["key1":"Value1", "key2":"Value2"]
let k = dict.keys
var a: [String]()
a.append(contentsOf: k)
This works for me.
NSDictionary is Class(pass by reference)
Dictionary is Structure(pass by value)
====== Array from NSDictionary ======
NSDictionary has allKeys and allValues get properties with
type [Any].
let objesctNSDictionary =
NSDictionary.init(dictionary: ["BR": "Brazil", "GH": "Ghana", "JP": "Japan"])
let objectArrayOfAllKeys:Array = objesctNSDictionary.allKeys
let objectArrayOfAllValues:Array = objesctNSDictionary.allValues
print(objectArrayOfAllKeys)
print(objectArrayOfAllValues)
====== Array From Dictionary ======
Apple reference for Dictionary's keys and values properties.
let objectDictionary:Dictionary =
["BR": "Brazil", "GH": "Ghana", "JP": "Japan"]
let objectArrayOfAllKeys:Array = Array(objectDictionary.keys)
let objectArrayOfAllValues:Array = Array(objectDictionary.values)
print(objectArrayOfAllKeys)
print(objectArrayOfAllValues)
This answer will be for swift dictionary w/ String keys. Like this one below.
let dict: [String: Int] = ["hey": 1, "yo": 2, "sup": 3, "hello": 4, "whassup": 5]
Here's the extension I'll use.
extension Dictionary {
func allKeys() -> [String] {
guard self.keys.first is String else {
debugPrint("This function will not return other hashable types. (Only strings)")
return []
}
return self.flatMap { (anEntry) -> String? in
guard let temp = anEntry.key as? String else { return nil }
return temp }
}
}
And I'll get all the keys later using this.
let componentsArray = dict.allKeys()
// Old version (for history)
let keys = dictionary.keys.map { $0 }
let keys = dictionary?.keys.map { $0 } ?? [T]()
// New more explained version for our ducks
extension Dictionary {
var allKeys: [Dictionary.Key] {
return self.keys.map { $0 }
}
}