coolcade coolcade - 5 months ago 62
Swift Question

Swift array reduction: cannot use mutating member on immutable value

I have the following code that attempts to consolidate elements of an array with redundant elements:

var items : [String] = ["hello", "world", "!", "hello"]

var mutableSet = Set<String>()

items.reduce(mutableSet, combine: { (set: Set<String>, element: String) in
return set.insert(element)
})


But
set.insert(element)
gives me the error
Cannot use mutating member on immutable value: 'set' is a 'let' constant
. What's wrong and how can I fix it?

Answer

In Swift, collections are value types. Value-typed variables declared with let (as implicitly are function parameters) cannot be modified. Additionally, your closure returns nothing, so reduce will probably not succeed.

I believe that reduce is not the best-suited tool for this task. Consider this for loop instead:

var set = Set<String>()
for element in items { set.insert(element) }

Another even simpler option would be to use the unionInPlace method:

var set = Set<String>()
set.unionInPlace(items)

Even better perhaps, create the set straight from the collection:

var set = Set<String>(items)