10

I have this simple struct.

struct Section {
    let store: Store
    var offers: [Offer]
}

In the VC, I have declared an array of these Sections at the top like so, fileprivate var sections: [Section] = []. And I add some Section objects to in the viewDidLoad().

Later, I need to delete some Offer objects from the offers array inside some Sections.

I iterate through the sections array to find the Section that contains the Offer that needs to be deleted.

for section in sections {
    if let i = section.offers.index(where: { $0.id == offer.id }) {
        section.offers.remove(at: i) // Cannot use mutating member on immutable value: 'section' is a 'let' constant
    }
}

But when I try to delete that particular Offer from the offers array, I get the error Cannot use mutating member on immutable value: 'section' is a 'let' constant.

How do I resolve this?

4 Answers 4

18

By default variables defined in the for are let and they cannot be altered. So you have to make it a var. Easier solution:

for var section in sections {
    if let i = section.offers.index(where: { $0.id == offer.id }) {
        section.offers.remove(at: i)
    }
}
Sign up to request clarification or add additional context in comments.

Comments

8

When you do the for loop of sections struct (value type) the section variables are immutable. You cannot modify directly their values. You will have to create a mutable version of each Section object, do the modification and assign back to the array (replace the modified object at the right index). For example:

sections = sections.map({
    var section = $0
    if let i = section.offers.index(where: { $0.id == offer.id }) {
        section.offers.remove(at: i)
    }
    return section
})

Comments

0

Since reference object on For loop is immutable you have to make an intermediate variable on which you have to play logic.

Also you are using value typed (Structure) you have to update on datasource from intermediate variable when you are done.

for j in 0 ..< sections.count {

    var section = sections[j]

    if let i = section.offers.index(where: { $0.id == offer.id }) {

        aSection.offers.remove(at: i) // Cannot use mutating member on immutable value: 'section' is a 'let' constant
        sections[j] = section
    }
}

Comments

0

When you use a for loop, the variable is a let constant. To fix it you should use this loop :

for index in 0..<sections.count {
    var section = sections[index]
    [...]
}

1 Comment

Since struct is a value-type, you need to later update the array with your edited value: sections[index] = section

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.