# For loop on the elements of a mutable struct

**URL:** <https://discourse.julialang.org/t/for-loop-on-the-elements-of-a-mutable-struct/94563>\
**Category:** General Usage\
**Tags:** struct\
**Created:** [February 13, 2023, 2:20pm UTC](https://discourse.julialang.org/t/for-loop-on-the-elements-of-a-mutable-struct/94563 "2023-02-13T14:20:25Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![fdekerme](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fdekerme/32/43574_2.png) [@fdekerme](https://discourse.julialang.org/u/fdekerme)\
**Post date:** [February 13, 2023, 2:20pm UTC](https://discourse.julialang.org/t/for-loop-on-the-elements-of-a-mutable-struct/94563/1 "2023-02-13T14:20:25Z")

</div>

Hi ! 😃  
I have a question about `mutable structs`. I have a model `model` composed of several compartments, each characterized by (say) 2 values `a` and `b`. I would like to make a for loop to test different values of `a` and `b` for these buckets. The following code does not work because` "type Model has no field compartment"`. Is this normal behavior, and if so 1) why? and 2) how to do otherwise?

Thanks ! 😃

```julia
mutable struct Compartment
    a::Int64
    b::Float64
end

Base.@kwdef mutable struct Model
    compartment1::Compartment
    compartment2::Compartment

    compartment_list::Vector{Compartment} = [compartment1, compartment2]
end

c1 = Compartment(2, 16.0)
c2 = Compartment(5, 67.0)

model = Model(compartment1 = c1, compartment2 = c2)

for compartment in model.compartment_list
    model.compartment.a +=1
    model.compartment.b += 6.3
end

```

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [February 13, 2023, 2:29pm UTC](https://discourse.julialang.org/t/for-loop-on-the-elements-of-a-mutable-struct/94563/2 "2023-02-13T14:29:17Z")

</div>

your `Model` has three fields: `compartment1, compartment2, compartment_list`

it does not have a field called `compartment`

---

<div class="post-metadata">

**Author:** ![Salmon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/salmon/32/22968_2.png) [@Salmon](https://discourse.julialang.org/u/Salmon)\
**Post date:** [February 13, 2023, 2:31pm UTC](https://discourse.julialang.org/t/for-loop-on-the-elements-of-a-mutable-struct/94563/3 "2023-02-13T14:31:48Z")

</div>

To elaborate on this, what you likely want to do is the following:

```julia

for compartment in model.compartment_list
    compartment.a +=1
    compartment.b += 6.3
end

```

note that in your loop you are already iterating over the compartments of your model

---

<div class="post-metadata">

**Author:** ![fdekerme](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fdekerme/32/43574_2.png) [@fdekerme](https://discourse.julialang.org/u/fdekerme)\
**Post date:** [February 13, 2023, 2:32pm UTC](https://discourse.julialang.org/t/for-loop-on-the-elements-of-a-mutable-struct/94563/4 "2023-02-13T14:32:20Z")

</div>

But the for loop is not able to treat `compartment` as a “variable” and replace it with `compartment1` and `compartment2`?

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [February 13, 2023, 2:33pm UTC](https://discourse.julialang.org/t/for-loop-on-the-elements-of-a-mutable-struct/94563/5 "2023-02-13T14:33:37Z")

</div>

inside your loop, the `compartment` is of type `Compartment`, which has two fields, `a` and `b`.

But look at this line

```julia
model.compartment.a +=1

```

the `model` here is the `Model()` you just defined outside of for loop, which does not have a field called `compartment`

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [February 13, 2023, 2:34pm UTC](https://discourse.julialang.org/t/for-loop-on-the-elements-of-a-mutable-struct/94563/6 "2023-02-13T14:34:50Z")

</div>

what you might wanted to do is this:

```julia
for compartment in model.compartment_list
    compartment.a +=1
    compartment.b += 6.3
end

```

---

<div class="post-metadata">

**Author:** ![fdekerme](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fdekerme/32/43574_2.png) [@fdekerme](https://discourse.julialang.org/u/fdekerme)\
**Post date:** [February 13, 2023, 2:38pm UTC](https://discourse.julialang.org/t/for-loop-on-the-elements-of-a-mutable-struct/94563/7 "2023-02-13T14:38:45Z")

</div>

> [@fdekerme](#):
>
> ```julia
> for compartment in model.compartment_list
> model.compartment.a +=1
> model.compartment.b += 6.3
> 
> ```

Oh great thank you very much! I thought that by doing like this, I will only modify the values of `c1` and `c2`, but not the values contained in `model`.

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [February 13, 2023, 2:40pm UTC](https://discourse.julialang.org/t/for-loop-on-the-elements-of-a-mutable-struct/94563/8 "2023-02-13T14:40:11Z")

</div>

c1 and c2 are the same things that are contained by model.

btw, in this case you actually don’t need `Model` itself being `mutable`, you should figure out why

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [February 13, 2023, 5:20pm UTC](https://discourse.julialang.org/t/for-loop-on-the-elements-of-a-mutable-struct/94563/9 "2023-02-13T17:20:33Z")

</div>

As a side note, you could iterate over the fields of `Model` without having an explicit list of its compartments:

```julia
julia> mutable struct Compartment
           a::Int64
           b::Float64
       end

julia> Base.@kwdef mutable struct Model
           compartment1::Compartment
           compartment2::Compartment
       end
Model

julia> c1 = Compartment(2, 16.0);

julia> c2 = Compartment(5, 67.0);

julia> model = Model(compartment1 = c1, compartment2 = c2)
Model(Compartment(2, 16.0), Compartment(5, 67.0))

julia> for compartment in fieldnames(Model)
           c = getfield(model,compartment)
           c.a += 1
           c.b += 6.3
       end

julia> c1
Compartment(3, 22.3)

julia> c2
Compartment(6, 73.3)

```

---

<div class="post-metadata">

**Author:** ![uniment](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uniment/32/24532_2.png) [@uniment](https://discourse.julialang.org/u/uniment)\
**Post date:** [February 13, 2023, 8:46pm UTC](https://discourse.julialang.org/t/for-loop-on-the-elements-of-a-mutable-struct/94563/10 "2023-02-13T20:46:14Z")

</div>

In addition, you can make `Model` iterable:

```julia
julia> Base.iterate(m::Model, n=1) = if n ≤ fieldcount(Model); getfield(m, n), n+1 end

julia> for comp in model
           comp.a += 1
           comp.b += 6.3
       end

julia> c1
Compartment(3, 22.3)

julia> c2
Compartment(6, 73.3)

```
