我希望能够在Swift中使用map
修改我的对象数组,而不会遍历每个元素。
在此之前能够做到这样的事情(更详细地描述here:
gnomes = gnomes.map { (var gnome: Gnome) -> Gnome in
gnome.age = 140
return gnome
}
感谢Erica Sadun和其他人,新提案已经完成,我们现在正在摆脱C风格的循环并在循环中使用var
。
在我的情况下,我首先收到警告,删除var
,然后发出错误gnome
是一个常数(自然)
我的问题是:我们如何更改map
内的数组或新样式的循环以便为Swift 3.0做好充分的准备?
答案 0 :(得分:19)
如果要保留该语法,只需使用(可变)临时变量
gnomes = gnomes.map { (gnome: Gnome) -> Gnome in
var mutableGnome = gnome
mutableGnome.age = 140
return mutableGnome
}
答案 1 :(得分:14)
(下面是Gnome
是引用类型的情况;一个类 - 因为您没有向我们展示您如何定义Gnome
。对于{{1}的情况1}}作为值类型(结构),请参阅@vadian:s answer)
删除Gnome
不会影响使用var
来突变引用类型对象数组的可变成员。即,您可以简单地使用旧方法(但省略.map
闭包签名中的var
。
.map
但是,如果您只想修改原始数组而不是将class Gnome {
var age = 42
}
var gnomes = [Gnome(), Gnome(), Gnome()]
gnomes = gnomes.map {
$0.age = 150
return $0
}
/* result */
gnomes.forEach { print($0.age) } // 3x 150
的结果分配给新数组,.map
可能比.forEach
更合适。< / p>
.map
答案 2 :(得分:1)
假设:
struct Gnome {
var age: Int = 0
}
var gnomes = Array(count: 5, repeatedValue: Gnome())
......有两个不错的选择。第一个是@vadian说的:
gnomes = gnomes.map{
var gnome = $0
gnome.age = 70
return gnome
}
虽然第二个控制了老化&#34; private
并简化了呼叫点的映射:
struct Gnome {
private(set) var age: Int = 0
func aged(age: Int) -> Gnome {
var gnome = self
gnome.age = age
// any other ageing related changes
return gnome
}
}
gnomes = gnomes.map{ $0.aged(140) }
当然,引用类型仍然在编程中占有一席之地,在这种情况下可能更适合。我们在这里遇到的摩擦表明我们正试图将这些结构视为对象。如果这是您需要的行为,那么您应该考虑将Gnome
作为class
实施。