Swift dictionary of nested arrays manipulation - cannot mutate nested array inside a dictionary
var dict = ["alpha": ["a", "b", "c", "d"]]
// output : ["alpha": ["a", "b", "c", "d"]]
var alphaList = dict["alpha"]
// output : {["a", "b", "c", "d"]
alphaList?.removeAtIndex(1)
// output : {Some "b"}
alphaList
// output : {["a", "c", "d"]}
dict
// output : ["alpha": ["a", "b", "c", "d"]]
Why doesn't the "dict" change? Is it because 'alphaList' is a copy of the array and not the actual array inside the dictionary? Can anyone point me to where in the Swift language documentation I can find this information?
What is the correct / functional way to manipulate the values โโof a (complex type) dictionary?
source to share
Good question yes, it creates a copy of the value in your case, this is the Array value
var alphaList = dict["alpha"]
/* which is the copy of original array
changing it will change the local array alphaList as you can see by your output */
output : {Some "b"}
To get the original array use
dict["alpha"]?.removeAtIndex(1)
Or update it with the key
alphaList?.removeAtIndex(1)
dict["alpha"] = alphaList
Apple: Assignment and Copying for Strings, Arrays and Dictionaries
The Swifts String, Array, and Dictionary types are implemented as structures. This means that strings, arrays and dictionaries are copied when they are assigned to a new constant or variable, or when they are passed to a function or method.
This behavior differs from NSString, NSArray, and NSDictionary in Foundation, which are implemented as classes rather than structures. NSString, NSArray, and NSDictionary instances are always assigned and passed as a reference to an existing instance, not a copy. "
source to share
Fast arrays and dictionaries are valid ( struct
) times. There is only one link to such an instance. Although NSArray
they NSDictonary
are of type class
and there can be multiple references to such instances.
The operator var alphaList = dict["alpha"]
makes a copy for ["a", "b", "c", "d"]
, so you cannot modify the original array.
If you want to change the original "alpha"
, you must use dict
as root variable:
dict["alpha"]?.removeAtIndex(1)
source to share
You're right alphaList
- it's a copy, so any changes you make to it are local and don't affect the original array. The documentation describes that Structures and Enumerations are type values .
The only way to make changes to the array after retrieving it from elsewhere is to pass the array to the function by reference using the parameter modifier inout
:
func modifyAlphaList(inout alphaList: [String]?) {
alphaList?.removeAtIndex(1)
}
modifyAlphaList(&dict["alpha"])
dict // (.0 "alpha", ["a", "c", "d"])
source to share