【发布时间】:2018-05-23 06:59:31
【问题描述】:
我们有一个案例,我们收到了一个Array<Any> 类型的对象,我们需要将其转换为Array<Codable>。如果原始数组中的任何一项不符合Codable,那么我们希望整个事情中止并返回nil。
或者当前的方法是手动循环遍历所有内容,一路测试,就像这样......
func makeCodable(sourceArray:Array<Any>) -> Array<Codable>?{
var codableArray = Array<Codable>()
for item in sourceArray{
guard let codableItem = item as? Codable else {
return nil
}
codableArray.append(codableItem)
}
return codableArray
}
但是,我想知道是否有更简单的方法可以使用 map 命令执行此操作,但如果无法映射任何元素,则需要将其短路。这就是我不确定是否可能。
比如这个伪代码……
func makeCodable(sourceArray:Array<Any>) -> Array<Codable>?{
return sourceArray.map({ $0 as? Codable});
}
这可能吗,还是我们原来的方式是正确/唯一的方式?
【问题讨论】:
-
当然
for方法是最有效的。它最多只迭代一次,它会尽快失败。好的旧循环并不是一件坏事,因为 Swift 容器提供了其他方便的方法。 -
您还可以检查您的数组是否包含不可编码的对象,如果为真则返回 nil 或映射元素。试试
return sourceArray.contains(where: {!($0 is Codable)}) ? nil : sourceArray.map { $0 as? Codable} -
@LeoDabus 这就是我的效率评论的用武之地。任何其他方法都需要最多两次迭代数组。
-
但它不会映射元素,如果存在,它会在第一个非 Codable 元素处破坏它
-
但不是吗?它必须检查它是否可映射,然后在实际执行映射时再次检查。同一循环上的两次迭代执行两次相同的检查。我开始认为我应该创建自己的
mapCompletely扩展来做这种事情。
标签: swift map-function codable