完全ではありませんが、 nschum の回答に基づいて構築されたこのバージョンは、オプションの引数 (オプションの型の配列ではありません) もサポートしています。
extension Array {
private func typeIsOptional() -> Bool {
return reflect(self[0]).disposition == .Optional
}
func contains<U : Equatable>(obj: U) -> Bool {
if isEmpty {
return false
}
if (typeIsOptional()) {
NSException(name:"Not supported", reason: "Optional Array types not supported", userInfo: nil).raise()
}
// cast type of array to type of argument to make it equatable
for item in self.map({ $0 as? U }) {
if item == obj {
return true
}
}
return false
}
// without this version, contains("foo" as String?) won't compile
func contains<U : Equatable>(obj: U?) -> Bool {
if isEmpty {
return false
}
if (typeIsOptional()) {
NSException(name:"Not supported", reason: "Optional Array types not supported", userInfo: nil).raise()
}
return obj != nil && contains(obj!)
}
}
オプションの配列がある場合、jtbandes のおかげで、このグローバル関数を使用して、非オプション (nil 引数が削除された) を含む配列のコピーを取得できます。
func unwrapOptionals<T>(a: [T?]) -> [T] {
return a.filter { $0 != nil }.map { $0! }
}
使用法:
1> func unwrapOptionals<T>(a: [T?]) -> [T] {
2. return a.filter { $0 != nil }.map { $0! }
3. }
4>
5> let foo = ["foo" as String?]
foo: [String?] = 1 value {
[0] = "foo"
}
6> let bar = unwrapOptionals(foo)
bar: [String] = 1 value {
[0] = "foo"
}
適切な対策として、型がオプションでない場合に配列を返すものを追加します。unwrapOptionals()
このようにして、オプションではない配列を呼び出した場合の実行時エラーを回避します。
func unwrapOptionals<T>(a: [T]) -> [T] {
return a
}
unwrapOptionals
内部で呼び出すことができると思うかもしれませんfunc contains<U : Equatable>(obj: U?)
。ただし、Element
配列拡張の型は単なる型であるため、これは機能しません。オプションの型であることを「認識」していません。したがって、 を呼び出すunwrapOptionals
と、2 番目のバージョンが呼び出され、オプションでいっぱいの配列が返されます。