Swift:避免命令式 For 循环
Swift: Avoid imperative For Loop
我在命令式中试图完成的事情:
var mapNames = [String]()
var mapLocation = [String]()
for valueMap in valueMaps {
if let name = valueMap.name {
mapNames.append(name)
}
if let location = valueMap.location {
mapLocation.append(location)
}
}
使用高阶函数或数组方法(array.filter
等)压缩上述代码并避免使用 for
循环的最佳方法是什么
这是我试过的,但是编译器报错:
let getArrayOfNames = valueMaps.filter() {
if let name = ([=12=] as valueMaps).name as [String]! {
return name;
}
}
let getArrayOfLocations = valueMaps.filter() {
if let type = ([=12=] as valueMaps).location as [String]! {
return type;
}
}
你需要 filter()
和 map()
:
let mapNames = valueMaps.filter( {[=10=].name != nil }).map( { [=10=].name! })
let mapLocations = valueMaps.filter( {[=10=].location != nil }).map( { [=10=].location! })
过滤器采用 谓词 作为参数(指定哪个
元素应包含在结果中),地图采用
一个 transformation 作为参数。你试图合并两者
方面进入过滤器,这是不可能的。
更新: 从 Swift 开始 2(?) 有一个 flatMap()
序列方法,它
可用于单步获取结果:
let mapNames = valueMaps.flatMap { [=11=].name }
闭包应用于所有数组元素,return值为一个
包含所有非零解包结果的数组。
filter() 函数需要将其闭包 return 布尔值 - 而不是您要存储在数组中的值。您可以将 filter 和 map 链接在一起以获得您想要的内容,然后:
let getArrayOfNames = valueMaps
.filter { [=10=].name != nil }
.map{ [=10=].name! }
或者,使用 reduce 在一个函数中完成:
let getArrayOfNames = valueMaps
.reduce([String]()) {
accu, element in
if let name = element.name {
return accu + [name]
} else {
return accu
}
}
其实reduce可以好一点:
let getArrayOfNames = valueMaps.reduce([String]()) {
(names, value) in names + (value.name.map{[[=12=]]} ?? [])
}
let getArrayOfLocations = valueMaps.reduce([String]()) {
(locs, value) in locs + (value.location.map{[[=12=]]} ?? [])
}
我在命令式中试图完成的事情:
var mapNames = [String]()
var mapLocation = [String]()
for valueMap in valueMaps {
if let name = valueMap.name {
mapNames.append(name)
}
if let location = valueMap.location {
mapLocation.append(location)
}
}
使用高阶函数或数组方法(array.filter
等)压缩上述代码并避免使用 for
循环的最佳方法是什么
这是我试过的,但是编译器报错:
let getArrayOfNames = valueMaps.filter() {
if let name = ([=12=] as valueMaps).name as [String]! {
return name;
}
}
let getArrayOfLocations = valueMaps.filter() {
if let type = ([=12=] as valueMaps).location as [String]! {
return type;
}
}
你需要 filter()
和 map()
:
let mapNames = valueMaps.filter( {[=10=].name != nil }).map( { [=10=].name! })
let mapLocations = valueMaps.filter( {[=10=].location != nil }).map( { [=10=].location! })
过滤器采用 谓词 作为参数(指定哪个 元素应包含在结果中),地图采用 一个 transformation 作为参数。你试图合并两者 方面进入过滤器,这是不可能的。
更新: 从 Swift 开始 2(?) 有一个 flatMap()
序列方法,它
可用于单步获取结果:
let mapNames = valueMaps.flatMap { [=11=].name }
闭包应用于所有数组元素,return值为一个 包含所有非零解包结果的数组。
filter() 函数需要将其闭包 return 布尔值 - 而不是您要存储在数组中的值。您可以将 filter 和 map 链接在一起以获得您想要的内容,然后:
let getArrayOfNames = valueMaps
.filter { [=10=].name != nil }
.map{ [=10=].name! }
或者,使用 reduce 在一个函数中完成:
let getArrayOfNames = valueMaps
.reduce([String]()) {
accu, element in
if let name = element.name {
return accu + [name]
} else {
return accu
}
}
其实reduce可以好一点:
let getArrayOfNames = valueMaps.reduce([String]()) {
(names, value) in names + (value.name.map{[[=12=]]} ?? [])
}
let getArrayOfLocations = valueMaps.reduce([String]()) {
(locs, value) in locs + (value.location.map{[[=12=]]} ?? [])
}