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?

+3


source to share


4 answers


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. "

+5


source


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)

      

+1


source


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"])

      

+1


source


This link should help

https://developer.apple.com/library/prerelease/mac/documentation/Swift/Conceptual/Swift_Programming_Language/ClassesAndStructures.html#//apple_ref/doc/uid/TP40014097-CH13-XID_150

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.

0


source







All Articles