我正在努力完成的任务:
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 = ($0 as valueMaps).name as [String]! {
return name;
}
}
let getArrayOfLocations = valueMaps.filter() {
if let type = ($0 as valueMaps).location as [String]! {
return type;
}
}
答案 0 :(得分:5)
您需要filter()
和map()
:
let mapNames = valueMaps.filter( {$0.name != nil }).map( { $0.name! })
let mapLocations = valueMaps.filter( {$0.location != nil }).map( { $0.location! })
过滤器将谓词作为参数(指定哪个 元素应该包含在结果中),并且地图需要 转换作为参数。你试图合并两者 进入过滤器的方面,这是不可能的。
更新:从Swift 2(?)开始,序列有flatMap()
个方法,
可以用来一步获得结果:
let mapNames = valueMaps.flatMap { $0.name }
闭包应用于所有数组元素,返回值为 包含所有非零未打包结果的数组。
答案 1 :(得分:2)
filter()函数需要其闭包来返回bool - 而不是要存储在数组中的值。您可以将过滤器和地图链接在一起以获得您想要的内容,然后:
let getArrayOfNames = valueMaps
.filter { $0.name != nil }
.map{ $0.name! }
或者,使用reduce:
在一个函数中执行此操作let getArrayOfNames = valueMaps
.reduce([String]()) {
accu, element in
if let name = element.name {
return accu + [name]
} else {
return accu
}
}
实际上,降低可能会更好一点:
let getArrayOfNames = valueMaps.reduce([String]()) {
(names, value) in names + (value.name.map{[$0]} ?? [])
}
let getArrayOfLocations = valueMaps.reduce([String]()) {
(locs, value) in locs + (value.location.map{[$0]} ?? [])
}