当其中一个元素在swift中转换失败时中止转换
在swift中,我们为数组提供了高阶函数,如map、filter、reduce等 但是如果我有一个数组,比如[Any]=[1,2,3,“1”] 我想把这个数组转换成Int数组,但是因为数组中有“1”,我的逻辑是接受整个数组无效,我会把它映射到一个空数组,比方说 在这种情况下,如何使用更高的函数 过滤很容易当其中一个元素在swift中转换失败时中止转换,swift,Swift,在swift中,我们为数组提供了高阶函数,如map、filter、reduce等 但是如果我有一个数组,比如[Any]=[1,2,3,“1”] 我想把这个数组转换成Int数组,但是因为数组中有“1”,我的逻辑是接受整个数组无效,我会把它映射到一个空数组,比方说 在这种情况下,如何使用更高的函数 过滤很容易 let array: [Any] = [1, 2, 3, "1"] let filtered = array.compactMap{ $0 as? Int} /// prints [1, 2,
let array: [Any] = [1, 2, 3, "1"]
let filtered = array.compactMap{ $0 as? Int}
/// prints [1, 2, 3]
但我希望最终结果是[],而不是[1,2,3]
如何使用高阶函数实现这一点 压缩映射
返回一个数组,其中包含使用此序列的每个元素调用给定转换的非nil结果
因此,使用compactMap
let array: [Any] = [1, 2, 3, "1"]
for case let element in array {
if let _ = element as? Int {
continue
} else {
print("\(element) isn't an Int, so array is invalid")
break
}
}
假设
数组为?[Int]??[]
不适用(例如,您需要应用更复杂的转换),您可以抛出一个错误
enum ConversionError: Error {
case notAllValuesWereInts
}
func convertOrThrow(_ input: Any) throws -> Int {
switch input {
case let int as Int: return int
default: throw ConversionError.notAllValuesWereInts
}
}
let array: [Any] = [1, 2, 3, "1"]
let ints: [Int]
do {
ints = try array.map(convertOrThrow)
} catch {
ints = []
}
print(ints)
在这种情况下,错误
用于控制流,不携带任何有用的信息,您可以使用try?
来简化操作:
let array: [Any] = [1, 2, 3, "1"]
let ints = (try? array.map(convertOrThrow)) ?? []
虽然这应该可以做到,因为您只想检查数组是否是整数数组
array as? [Int] ?? []
但如果您不想使用上面的代码,您可能会对以下代码感兴趣
let filtered = array.filter{($0.self as? Int) == nil}.count == 0 ? array as! [Int] : []
如果有任何元素不是Int
数组,则上述代码生成[]
?[Int]??[]
没有优雅的方法可以做到这一点。不能在高阶函数中使用break,continue。@dan-Yup,但需要进行一些转换。我知道我举了一个非常平凡的例子。但是假设它们都是[Int],但是我想把它们转换成一个元素小于100的有效数组。如果任何元素未能通过此转换,我应该返回一个空数组,而不是一个经过筛选的数组one@ShreeramBhat您可以throw
@Alexander再次使用try-catch进行投掷和处理这对于此类工作来说是一种优雅的方式吗?。最好使用for循环。