我有以下代码尝试合并数组的冗余元素:
var items : [String] = ["hello", "world", "!", "hello"]
var mutableSet = Set<String>()
items.reduce(mutableSet, combine: { (set: Set<String>, element: String) in
return set.insert(element)
})
set.insert(element)
给了我错误Cannot use mutating member on immutable value: 'set' is a 'let' constant
。什么错了,我该如何解决?
答案 0 :(得分:2)
在Swift中,集合是值类型。使用let
声明的值类型变量(隐式地是函数参数)无法修改。此外,您的闭包不返回任何内容,因此reduce
可能不会成功。
我认为reduce
不是最适合此任务的工具。请考虑使用此for
循环:
var set = Set<String>()
for element in items { set.insert(element) }
另一个更简单的选择是使用unionInPlace
方法:
var set = Set<String>()
set.unionInPlace(items)
或许更好,直接从集合创建集合:
var set = Set<String>(items)
答案 1 :(得分:2)
OP代码的问题在于reduce中的累加器是不可变的,所以它不允许你使用变异函数insert()。
一个整洁的解决方案是在如下的Set的扩展中定义一个名为insertion()的insert()的非变异等价物。
extension Set {
//returns a new set with the element inserted
func inserting(_ element: Element) -> Set<Element> {
var set = self
set.insert(element)
return set
}
}
现在我们可以按如下方式编写reduce
var items : [String] = ["hello", "world", "!", "hello"]
let set = items.reduce(Set<String>()){ accumulator, element in
accumulator.inserting(element)
}
答案 2 :(得分:0)
返回的'set'值是一个常量。这很重要,因为它是累加器,它表示迄今累积的值。它不应该在关闭时改变。
以下是我正在进行的一个项目的示例,我希望在许多戏剧表演中找到所有独特的表演者。注意我如何使用union,它不会修改常量值'performers',而是使用它来产生一个新值。
RouteBase