从对象数组中获取属性值数组
Posted
技术标签:
【中文标题】从对象数组中获取属性值数组【英文标题】:Get an array of property values from an object array 【发布时间】:2015-02-08 11:21:58 【问题描述】:有一个类叫Employee
。
class Employee
var id: Int
var firstName: String
var lastName: String
var dateOfBirth: NSDate?
init(id: Int, firstName: String, lastName: String)
self.id = id
self.firstName = firstName
self.lastName = lastName
我有一个Employee
对象数组。我现在需要的是将该数组中所有这些对象的id
s 提取到一个新数组中。
我也发现了类似的question。但它在 Objective-C 中,所以它使用 valueForKeyPath
来完成此操作。
如何在 Swift 中做到这一点?
【问题讨论】:
【参考方案1】:您可以使用map
方法,它将某种类型的数组转换为另一种类型的数组 - 在您的情况下,从Employee
的数组到Int
的数组:
var array = [Employee]()
array.append(Employee(id: 4, firstName: "", lastName: ""))
array.append(Employee(id: 2, firstName: "", lastName: ""))
let ids = array.map $0.id
【讨论】:
这就是map
所做的——它将Employee
的数组转换为Int
的数组,并用id
字段填充。这相当于说“从Employee
的所有实例中提取id字段并将它们放入一个数组中”
@Isuru,这个答案正是你想要的。它从Employee
s 数组中的所有id
值中创建一个名为ids
的新数组。请注意,它使原始数组保持不变。
看起来在 Swift 2 beta 中正确的语法应该是 array.map( $0.id )
如果您使用的是可选的,请确保您!它。花了我几个小时。
@Chris 强制展开通常是一种不好的做法,因为如果为零,它将导致应用程序崩溃。仅在严格要求时使用它,并且更喜欢可选绑定(或任何其他“软”展开)【参考方案2】:
Swift 5 提供了许多方法来从类似对象的数组中获取属性值数组。根据您的需要,您可以选择以下六个 Playground 代码示例之一来解决您的问题。
1。使用map
方法
使用 Swift,符合Sequence
协议的类型有一个map(_:)
方法。下面的示例代码展示了如何使用它:
class Employee
let id: Int, firstName: String, lastName: String
init(id: Int, firstName: String, lastName: String)
self.id = id
self.firstName = firstName
self.lastName = lastName
let employeeArray = [
Employee(id: 1, firstName: "Jon", lastName: "Skeet"),
Employee(id: 2, firstName: "Darin", lastName: "Dimitrov"),
Employee(id: 4, firstName: "Hans", lastName: "Passant")
]
let idArray = employeeArray.map( (employee: Employee) -> Int in
employee.id
)
// let idArray = employeeArray.map $0.id // also works
print(idArray) // prints [1, 2, 4]
2。使用for
循环
class Employee
let id: Int, firstName: String, lastName: String
init(id: Int, firstName: String, lastName: String)
self.id = id
self.firstName = firstName
self.lastName = lastName
let employeeArray = [
Employee(id: 1, firstName: "Jon", lastName: "Skeet"),
Employee(id: 2, firstName: "Darin", lastName: "Dimitrov"),
Employee(id: 4, firstName: "Hans", lastName: "Passant")
]
var idArray = [Int]()
for employee in employeeArray
idArray.append(employee.id)
print(idArray) // prints [1, 2, 4]
3。使用while
循环
请注意,对于 Swift,在幕后,for
循环只是在 sequence
的迭代器上的 while
循环(有关详细信息,请参阅 IteratorProtocol)。
class Employee
let id: Int, firstName: String, lastName: String
init(id: Int, firstName: String, lastName: String)
self.id = id
self.firstName = firstName
self.lastName = lastName
let employeeArray = [
Employee(id: 1, firstName: "Jon", lastName: "Skeet"),
Employee(id: 2, firstName: "Darin", lastName: "Dimitrov"),
Employee(id: 4, firstName: "Hans", lastName: "Passant")
]
var idArray = [Int]()
var iterator = employeeArray.makeIterator()
while let employee = iterator.next()
idArray.append(employee.id)
print(idArray) // prints [1, 2, 4]
4。使用符合IteratorProtocol
和Sequence
协议的struct
class Employee
let id: Int, firstName: String, lastName: String
init(id: Int, firstName: String, lastName: String)
self.id = id
self.firstName = firstName
self.lastName = lastName
struct EmployeeSequence: Sequence, IteratorProtocol
let employeeArray: [Employee]
private var index = 0
init(employeeArray: [Employee])
self.employeeArray = employeeArray
mutating func next() -> Int?
guard index < employeeArray.count else return nil
defer index += 1
return employeeArray[index].id
let employeeArray = [
Employee(id: 1, firstName: "Jon", lastName: "Skeet"),
Employee(id: 2, firstName: "Darin", lastName: "Dimitrov"),
Employee(id: 4, firstName: "Hans", lastName: "Passant")
]
let employeeSequence = EmployeeSequence(employeeArray: employeeArray)
let idArray = Array(employeeSequence)
print(idArray) // prints [1, 2, 4]
5。使用Collection
协议扩展和AnyIterator
class Employee
let id: Int, firstName: String, lastName: String
init(id: Int, firstName: String, lastName: String)
self.id = id
self.firstName = firstName
self.lastName = lastName
extension Collection where Iterator.Element: Employee
func getIDs() -> Array<Int>
var index = startIndex
let iterator: AnyIterator<Int> = AnyIterator
defer index = self.index(index, offsetBy: 1)
return index != self.endIndex ? self[index].id : nil
return Array(iterator)
let employeeArray = [
Employee(id: 1, firstName: "Jon", lastName: "Skeet"),
Employee(id: 2, firstName: "Darin", lastName: "Dimitrov"),
Employee(id: 4, firstName: "Hans", lastName: "Passant")
]
let idArray = employeeArray.getIDs()
print(idArray) // prints [1, 2, 4]
6。使用KVC和NSArray
的value(forKeyPath:)
方法
请注意,此示例要求 class Employee
继承自 NSObject
。
import Foundation
class Employee: NSObject
@objc let id: Int, firstName: String, lastName: String
init(id: Int, firstName: String, lastName: String)
self.id = id
self.firstName = firstName
self.lastName = lastName
let employeeArray = [
Employee(id: 1, firstName: "Jon", lastName: "Skeet"),
Employee(id: 2, firstName: "Darin", lastName: "Dimitrov"),
Employee(id: 4, firstName: "Hans", lastName: "Passant")
]
let employeeNSArray = employeeArray as NSArray
if let idArray = employeeNSArray.value(forKeyPath: #keyPath(Employee.id)) as? [Int]
print(idArray) // prints [1, 2, 4]
【讨论】:
巨大的......据我所知,这是完整的可能方法列表 可能已经停在#1(特别是注释掉的行),但很好的详尽列表!以上是关于从对象数组中获取属性值数组的主要内容,如果未能解决你的问题,请参考以下文章