Change a dictionary's key in Swift
Swift 3
func switchKey<T, U>(_ myDict: inout [T:U], fromKey: T, toKey: T) {
if let entry = myDict.removeValue(forKey: fromKey) {
myDict[toKey] = entry
}
}
var dict = [Int:String]()
dict[1] = "World"
dict[2] = "Hello"
switchKey(&dict, fromKey: 1, toKey: 3)
print(dict) /* 2: "Hello"
3: "World" */
Swift 2
func switchKey<T, U>(inout myDict: [T:U], fromKey: T, toKey: T) {
if let entry = myDict.removeValueForKey(fromKey) {
myDict[toKey] = entry
}
}
var dict = [Int:String]()
dict[1] = "World"
dict[2] = "Hello"
switchKey(&dict, fromKey: 1, toKey: 3)
print(dict) /* 2: "Hello"
3: "World" */
Converting Dictionary Key type in Swift 5 with Dictionary(uniqueKeysWithValues:)
You'd better explicitly highlight type like this:
extension KeyedParameters {
var parameters: Parameters {
return Parameters(uniqueKeysWithValues:
self.map { (key, value) in (key.rawValue, value) }
)
}
}
Worked for me.
How to replace dictionary particular key value using Swift
Something is not right with your equality operator: you are asking if two items are the same - and if they are the same then check if something in them is different :)
Try to search array with first method: if you find (and you will) any item matching the case continue with your work.
Something like this:
if let aValue = UserDefaults.standard.object(forKey: "a") as? [String:Any] {
let tag = TagModel(dict: aValue)
if items.contains(tag) == false {
items.append(tag)
} else if let existing = items.first(where: { $0 == tag}), existing.tagName != tag.tagName {
// replace item
let index = items.firstIndex(of: tag)!
items[index] = tag
}
}
Change the type of the key in a dictionary
You can use compactMap
on the sequence of key/value pairs of the original
dictionary to extract those with an integer key, and Dictionary(uniqueKeysWithValues:)
to create a new dictionary:
let myDict: [String: [String: Any]] = [
"test": [ "0": [ "test" : "test" ]],
"123": [ "1" :[ "foo": "bar" ] ]
]
let myDict2 = Dictionary(uniqueKeysWithValues: myDict.compactMap { (key, value) in
Int(key).map { ($0, value) }
})
print(myDict2) // [123: ["1": ["foo": "bar"]]]
print(type(of: myDict2)) // Dictionary<Int, Dictionary<String, Any>>
Here it is assumed that all strings represent different integers. If that
is not guaranteed then use
let myDict2 = Dictionary(myDict.compactMap { (key, value) in
Int(key).map { ($0, value) }
}, uniquingKeysWith: { $1 })
instead. The additional parameter determines which value
is used in the case of duplicate keys, with { $1 }
the last one
“wins”.
Swift replace key value in array of dictionaries with nested dictionaries
Here is a solution with a recursive function that replaces all values for a given key.
func update(_ dict: [String: Any], set value: Any, for key: String) -> [String: Any] {
var newDict = dict
for (k, v) in newDict {
if k == key {
newDict[k] = value
} else if let subDict = v as? [String: Any] {
newDict[k] = update(subDict, set: value, for: key)
} else if let subArray = v as? [[String: Any]] {
var newArray = [[String: Any]]()
for item in subArray {
newArray.append(update(item, set: value, for: key))
}
newDict[k] = newArray
}
}
return newDict
}
Note that it doesn't check what type the existing value is but directly replaces it with the new value. Also the code assumes the only types of nested arrays are arrays of dictionaries.
For the array this function can be used with map
let out = data.map { update($0, set: "newValue", for: "id")}
Does adding a key value pair to a dictionary change the pointer's address?
Dictionaries in Swift are value, not reference, type like NSDictionary
. Updates to the copy won't be reflected in the original. Here's a minimal example:
var a = ["name": "John", "location": "Chicago"]
var b = a
b["title"] = "developer"
print(a) // a does not contain the 'title' key
print(b)
You need to update the original after updating the copy. You can delve into stuffs like UnsafeMutablePointer<T>
but it's a dark road down there.
Is there any way in Swift 3 to update a Dictionary key value and get the previous value in one operation?
let previousValue = data.updateValue(newValue, forKey: key)
Related Topics
Swift: How to Fix Infinite Loop When Adding a Value to a Firebase Variable
Why Upload Alamofire Background Request Don't Executes in Background
Implementing Stringliteralconvertible on Nsurl
Swift: Label Text --> "Fatal Error: Unexpectedly Found Nil While Unwrapping an Optional Value"
How to Check If a Type Is Optional in Swift
Crash When Running on Device After Second Launch
How, Exactly, Do I Render Metal on a Background Thread
Way to Purge All But One Object Types (Models) in a Realm
How Marquee Text of Label on Swift
Expression Pattern of Type 'String' Cannot Match Values of Type 'Nsstoryboardsegue.Identifier
Instance Member Cannot Be Used on Type | Closures
Parse.Com Pfgeopoint.Geopointforcurrentlocationinbackground Not Doing Anything
Cabasicanimation Creates Empty Default Value Copy of Calayer