扩展Swift数组以按类型过滤元素

编程入门 行业动态 更新时间:2024-10-24 22:20:42
本文介绍了扩展Swift数组以按类型过滤元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

如何将swift数组扩展为访问特定类型的成员?

How can a swift array be extended to access members of a particular type?

如果数组包含从同一个超类继承的多个类的实例,则此方法相关。理想情况下,它将适当地执行类型检查。

This is relevant if an array contains instances of multiple classes which inherit from the same superclass. Ideally it would enforce type checking appropriately.

使用 filter(_:)方法可以正常工作,但确实可以保证类型安全。例如:

Using the filter(_:) method works fine, but does enforce type safety. For example:

protocol MyProtocol { } struct TypeA: MyProtocol { } struct TypeB: MyProtocol { } let myStructs:[MyProtocol] = [ TypeA(), TypeA(), TypeB() ] let filteredArray = myStructs.filter({ $0 is TypeA })

filteredArray 包含正确的值,但是类型保持为 [MyProtocol] 而不是 [TypeA] 。我希望将最后一个替换为 letfilteredArray = myStructs.filter({$ 0是TypeA})! [TypeA] 可以解决该问题,但是项目失败,并显示 EXEC_BAD_INSTRUCTION ,我不明白。也许类型转换数组是不可能的?

the filteredArray contains the correct values, but the type remains [MyProtocol] not [TypeA]. I would expect replacing the last with let filteredArray = myStructs.filter({ $0 is TypeA }) as! [TypeA] would resolve that, but the project fails with EXEC_BAD_INSTRUCTION which I do not understand. Perhaps type casting arrays is not possible?

理想情况下,此行为可以包装在数组扩展中。以下内容无法编译:

Ideally this behavior could be wrapped up in an array extension. The following doesn't compile:

extension Array { func objectsOfType<T:Element>(type:T.Type) -> [T] { return filter { $0 is T } as! [T] } }

这里似乎至少有两个问题:类型约束 T:Element 似乎不起作用。我不确定基于泛型类型添加约束的正确方法是什么。我的目的是说 T 是 Element 的子类型。另外,在第3行上存在编译时错误,但这可能与传播错误相同。

Here there seem to be at least two problems: the type constraint T:Element doesn't seem to work. I'm not sure what the correct way to add a constraint based on a generic type. My intention here is to say T is a subtype of Element. Additionally there are compile time errors on line 3, but this could just be the same error propagating.

推荐答案

SequenceType 具有 flatMap()方法,该方法用作可选过滤器:

SequenceType has a flatMap() method which acts as an "optional filter":

extension SequenceType { /// Return an `Array` containing the non-nil results of mapping /// `transform` over `self`. /// /// - Complexity: O(*M* + *N*), where *M* is the length of `self` /// and *N* is the length of the result. @warn_unused_result @rethrows public func flatMap<T>(@noescape transform: (Self.Generator.Element) throws -> T?) rethrows -> [T] }

结合了Matt的建议使用作为?代替是,您可以将其用作

Combined with matt's suggestion to use as? instead of is you can use it as

let myStructs:[MyProtocol] = [ TypeA(), TypeA(), TypeB() ] let filteredArray = myStructs.flatMap { $0 as? TypeA }

现在 filteredArray 的类型为推断为 [TypeA] 。

作为扩展方法,应为

extension Array { func objectsOfType<T>(type:T.Type) -> [T] { return flatMap { $0 as? T } } } let filteredArray = myStructs.objectsOfType(TypeA.self)

注意:对于 Swift> = 4.1,用 compactMap替换 flatMap

Note: For Swift >= 4.1, replace flatMap by compactMap.

更多推荐

扩展Swift数组以按类型过滤元素

本文发布于:2023-11-22 19:38:27,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1618748.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:数组   元素   类型   Swift

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!