swift - 如何从 [AnyObject] 数组中过滤特定类型的对象
问题描述
是否可以过滤 [AnyObject] 数组以产生给定类型的所有元素,而不是其他元素?
如果在编译时知道类型,我可以这样做:
class MyClass1: CustomStringConvertible {
var value: Int
var description: String {
return "MyClass1: \(value)"
}
init(_ value: Int) {
self.value = value
}
}
class MyClass2: CustomStringConvertible {
var value: Int
var description: String {
return "MyClass1: \(value)"
}
init(_ value: Int) {
self.value = value
}
}
class MySubClass1: MyClass1 {
override var description: String {
return "MySubClass1: \(value)"
}
}
let a1 = MySubClass1(1)
let a2 = MySubClass1(2)
let b1 = MyClass1(3)
let b2 = MyClass2(4)
let array: [AnyObject] = [a1, b1, a2, b2]
func getClass1ObjectsFromArray(_ array: [AnyObject]) -> [MyClass1] {
return array.compactMap( { $0 as? MyClass1 })
}
func getSubClass1ObjectsFromArray(_ array: [AnyObject]) -> [MySubClass1] {
return array.compactMap( { $0 as? MySubClass1 })
}
print(getClass1ObjectsFromArray(array))
print(getSubClass1ObjectsFromArray(array))
印刷:
[MySubClass1: 1, MyClass1: 3, MySubClass1: 2]
[MySubClass1: 1, MySubClass1: 2]
对于我想要过滤的每种类型,我都必须编写一个单独的函数。这对我来说看起来很丑陋,并且当要选择的类型仅在运行时才知道时将不起作用。
问题:
有没有通用的方法来编写这样的函数?最好是这样的:
func getObjectsOfType(_ type: TypeExpression, fromArray array: [AnyObject])
-> [TypeExpression] {
...
}
或任何其他方式来实现这一目标?
谢谢你的帮助!
解决方案
我想你可以使用这样的东西......
let filteredArray = array.compactMap { $0 as? RequiredType }
这将过滤数组并返回一个仅包含您想要的类型的类型化数组。
警告
话说回来。在 Swift 中,您应该尽可能避免使用异构数组。数组实际上应该只包含一种类型的项目。
一些代码测试...
在游乐场测试...
let array: [Any] = [1, "hello", 3, 3.1415, "world"]
let filteredArray = array.compactMap { $0 as? String }
filteredArray
输出:
filteredArray = ["hello", "world"]
编辑 1
你也可以创建一个像这样的通用函数......
func filter<T>(array: [Any]) -> [T] {
return array.compactMap { $0 as? T }
}
let filteredArray: [String] = filter(array: array)
然后,这将根据您想要的输出数组的类型进行过滤。
我不确定你在运行时只知道你想要的类型是什么意思。你能举一个更具体的例子来说明你的意思吗?
编辑 2
另一种可能性是这样的通用函数......
func filter<T>(array: [Any], byType typeObject: T) -> [T] {
return array.compactMap { $0 as? T }
}
let filteredArray = filter(array: array, byType: "some string")
这使用第二个参数的类型信息来按该类型的项目过滤数组。
编辑 3
如果你不喜欢传入类型的实例,那么你可以传递类型本身......
func filter<T>(array: [Any], byType typeObject: T.Type) -> [T] {
return array.compactMap { $0 as? T }
}
let filteredArray = filter(array: array, byType: String.self)
但我不确定你能从中得到什么,而不是一开始就按字符串过滤?
推荐阅读
- python-3.x - 这是子集和解决方案吗?
- java - 使用同一会话的多个事务的示例
- javascript - 多个表单在最后一个表单上提交 PHP
- amazon-web-services - 使用层还是调用另一个 lambda?
- python - selenium 获取 PLP 页面中每个产品元素的部分屏幕截图
- google-analytics - 如何使用 Tableau 计算字段删除 GA Page 查询参数?
- html - 告诉 Angular 自定义元素
- selenium - 无法在 Selenium Java 中找到选项卡元素
- c++ - 程序正在生成“错误 C4430:缺少类型说明符 - 假定为 int”。Skill.h 文件中带有有效用户定义对象的错误消息
- python - 为什么 python 日期时间在 {Date}2016-11-22T11:49:21.826-05:00 失败,即使格式匹配