Obtenga una matriz de valores de propiedad de una matriz de objects

Hay una class llamada 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 } } 

Y tengo una variedad de objects Employee . Lo que ahora necesito es extraer los id . De todos esos objects en esa matriz en una nueva matriz.

También encontré esta pregunta similar. Pero está en Objective-C por lo que está utilizando valueForKeyPath para lograr esto.

¿Cómo puedo hacer esto en Swift?

Puede usar el método de map , que transforma una matriz de un tipo determinado en una matriz de otro tipo, en su caso, desde una matriz de Employee hasta una matriz de 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 ofrece muchas forms de get una matriz de valores de properties de una variedad de objects similares. De acuerdo con sus necesidades y gustos, puede elegir uno de los siguientes seis ejemplos de códigos de juegos para resolver su problema.


1. Usar el método del map

Swift proporciona un método de map(_:) para types que se ajustan al protocolo de Sequence (incluido el Array ). (ver también Transformar una matriz )

 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. Usar for bucle

 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. Usar while loop

Tenga en count que con Swift, detrás de las escenas, un bucle for es solo un ciclo de while sobre el iterador de una sequence (ver IteratorProtocol para más detalles).

 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. Utilizando una struct que se ajuste a los protocolos IteratorProtocol y 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. Utilizando la extensión del protocolo de AnyIterator y 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. Utilizando el método de value(forKeyPath:) KVC y NSArray value(forKeyPath:)

Tenga en count que este ejemplo requiere que el class Employee henetworkinge de NSObject .

 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] } 

Consulte el repository Iterating-over-arrays de GitHub para ver más ejemplos.