我想写一个Array
的扩展名,它可以安全地返回自己的解包版本。
我可以使用像这样的通用方法:
func unwrapElements<T>(array: [T?]) -> [T] {
let filtered: [T?] = array.filter{ $0 != nil }
let unwrapped: [T] = filtered.map { $0! }
return unwrapped
}
我可以这样称呼它:
let sparseNames: [String?] = ["alice", "bob", nil, "doug", nil, nil, "george", "hubert"]
let names: [String] = unwrapElements(sparseNames)
其中names
最终为["alice", "bob", "doug", "george", "hubert"]
,并且可以安全地迭代并处理每个元素。
但是,我想这样称呼它:
let names = sparseNames.unwrapElements()
我看过一些类似的问题(like this one)但是他们没有解决如何将方法创建为扩展名。
(这是用Xcode6.1标记的,表示我正在使用的Swift版本)
注意:Swift 1.2 Beta 3引入了flatMap
函数,它有助于可选地链接数组。看到这个优秀的blog post here
答案 0 :(得分:3)
你现在无法在Swift中做到这一点。要将该函数添加为Array
的扩展名,您必须以某种方式标记它只能使用某些类型的数组进行调用:具有可选值的那些作为亚型。不幸的是,您无法进一步专门化泛型类型,因此全局函数是唯一可行的方法。
这与Array
具有sort
方法的原因相同,该方法将比较函数作为参数,但它没有sort
只有{#1}}工作&#34;如果数组中有Comparable
个成员 - 要获得这种功能,你必须查看顶级排序:
func sort<T : Comparable>(inout array: [T])
答案 1 :(得分:1)
您是否尝试过使用filter
和map
?
let array: [String?] = ["Hello", nil, "World"]
let unwrapped = array.map{$0 ?? nil}.filter{$0 != nil}.map{$0!}
println("unwrapped: \(unwrapped)")
// prints "unwrapped: [Hello, World]"
如果可能,第一个map
使用Nil Coalescing Operator解包。虽然,我返回nil
,因为以下过滤器会删除所有nil
值。最后map
执行实际解包。
答案 2 :(得分:0)
你可以这样做。方法如下:
extension Array {
func catOptionals<A>() -> [A] where Element == A? {
return self.flatMap{ $0 }
}
}