kelan.io

Mutating Arrays of Structs in Swift

Structs and arrays in Swift have value semantics, which means that each time you assign them to a new variable, you get a new copy. This can make it a little tricky to deal with nested structures, such as an array of structs.

Let's try a few things. 1

Given this array of structs, we want to modify a field in each struct. Note that arrays are value types too.
struct S {
    var value: String = "initial"
}
var array = [ S(), S() ]
If we try to use a for-in loop, we will only modify a copy of each array element, and leave the original array un-modified.
for var s in array {
    s.value = "changed"
    print("element is now: \(s.value)")
}

print("but array is still: \(array)")
s is now: changed s is now: changed

but array is still: [S(value: "initial"), S(value: "initial")]
We can use map(), modify each element, and assign the resulting array back to the array variable.
array = array.map { (var s: S) -> S in
    s.value = "mapped"
    return s
}
print(array)



[S(value: "mapped"), S(value: "mapped")]
Subscripting the array will successfully modify it "in place".
array[0].value = "subscripted"
print(array)
[S(value: "subscripted"), S(value: "mapped")]
We can do that in a loop, which isn't great, but isn't too terrible.
for i in array.indices {
    array[i].value = "subscripted in loop"
}
print(array)

[S(value: "subscripted in loop"), S(value: "subscripted in loop")]

So, I don't have a great solution, but it is something that I've run into a few times so far (as I try to use structs more and more), so I wanted to explore it here. If you have any feedback or suggestions, I'd be happy to hear about them.


  1. This is a new post format I’m working on for explaining code with comments and output along side each chunk of code. It’s inspired by things like the Go by Example format, and CoffeeScript documentation . I like it so far.