从一个对象数组中获取一组属性值
有一个叫做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
提取到一个新的数组中。
我也发现了这个类似的问题 。 但它在Objective-C中,所以它使用valueForKeyPath
来完成这个。
我怎么能在Swift中做到这一点?
你可以使用map
方法,它将一个特定types的数组转换成另一个types的数组 – 在你的情况下,从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 }
Swift 3提供了很多方法从一个类似对象的数组中获取一组属性值。 根据您的需求和口味,您可以select以下六个Playground代码示例中的一个来解决您的问题。
1.使用map
方法
Swift为符合Sequence
协议(包括Array
)的types提供了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
的迭代器(更多细节参见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
协议的结构
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
inheritance。
import Foundation class Employee: NSObject { 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] }
有关更多示例,请参阅GitHub的遍历数组回购 。