0

i have an array of class objects and i want to remove one of them at an specific index. The class contains simples variables. I tried to use the method removeAtIndex(index). But i am getting the error: Immutable value of type '[FieldData]' only has mutating members named 'removeAtIndex' I found that to solve this i should write mutating before the func of my method. But now i am getting the error: 'mutating' isn't valid on methods in classes or class-bound protocols

Can someone point me in the right direction to an answer, am i wrong in using a class for this? Or what is my problem here?

Thanks for the help.

general class definition:

class FieldData {    
    //string variables

    init(variables) {
        ...
    }
}

method definition

mutating func WandBestandEntf(fields: [FieldData]) -> [FieldData]? {
    for var n = 0 as Int; n < fields.count; n++ {
        if fields[n].name == "something" || fields[n].name == "other thing" {
            fields.removeAtIndex(n)
        }
    }
}
0

2 Answers 2

4

In swift function parameter are constant by default. so you can't change it.

In your method just add var before parameter name.

func WandBestandEntf(var fields: [FieldData]) -> [FieldData]? {
    for var n = 0 as Int; n < fields.count; n++ {
       if fields[n].name == "something" || fields[n].name == "other thing" {
        fields.removeAtIndex(n)
       }
    }
    return fields
 } 
Sign up to request clarification or add additional context in comments.

2 Comments

Swiftification: fields.filter { strings.contains($0.name) } where let strings = ["the", "things"]. This yields the same output but heavily uses the nice features in Swift which makes your code look much nicer, also you can directly see what the function does: it filters the list for every item whose name is contained in the given strings.
Prepending var to parameters will be deprecated in Swift 3. Check out the inout approach described in another answer here.
4

Dhaval Thanki's answer is one way to solve the problem. For the same of completeness, there's another way to achieve the same, by passing the parameter to the method by reference instead of by value:

func WandBestandEntf(inout fields: [FieldData]) {
    for var n = 0 as Int; n < fields.count; n++ {
        if fields[n].name == "something" || fields[n].name == "other thing" {
            fields.removeAtIndex(n)
        }
    }
}

The inout modifier tells the method that the fields parameter is passed by reference, hence it can be updated inside the method body, and any change made to it will be performed on the original data, and not a copy of it (as it happens by using var).

Since changes happen in place, there's no need to return the updated data.

Also note that in order to make explicit that the parameter is passed by reference, when invoking the method it must be prefixed by the & operator, which means "reference to":

var array = [...]
WandBestandEntf(&array)

Last, note that the parameter passed to the method must be mutable (i.e. declared with var). Trying to pass a reference to an immutable will raise an obvious compilation error:

let array = [...]
WandBestandEntf(&array) // Error: Cannot assign to immutable value of type '[FieldData]'

Comments

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.