Bir nesne dizisinden özellik değerleri dizisi alın


113

Adlı bir sınıf var 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
    }
}

Ve bir dizi Employeenesnem var. Şimdi ihtiyacım olan şey id, o dizideki tüm bu nesnelerin 'lerini yeni bir diziye çıkarmak .

Ben de bu benzer soruyu buldum . Ama bu Objective-C'de, bu yüzden bunu valueForKeyPathbaşarmak için kullanıyor .

Bunu Swift'de nasıl yapabilirim?

Yanıtlar:


235

Kullanabilirsiniz mapBelirli bir türdeki bir diziyi başka türden bir diziye dönüştüren yöntemi - sizin durumunuzda, diziden Employeediziye Int:

var array = [Employee]()
array.append(Employee(id: 4, firstName: "", lastName: ""))
array.append(Employee(id: 2, firstName: "", lastName: ""))

let ids = array.map { $0.id }

1
İşte mapböyle yapar - bir dizisini alanla dolu Employeebir diziye dönüştürür . Bu, "kimlik alanını tüm örneklerinden çıkar ve bir diziye koy " demeye eşdeğerdirIntidEmployee
Antonio

4
@Isuru, bu cevap tam olarak istediğinizi yapıyor. S dizisindeki idstüm iddeğerleri içeren yeni bir dizi oluşturur Employee. Unutmayın, orijinal diziyi olduğu gibi bırakır.
vacawama

2
Swift 2 array.map( { $0.id })
beta'da

10
isteğe bağlı kullanıyorsanız, emin olun! o. Saatlerimi aldı.
Chris

2
@Chris zorla sarmalamadan çıkma genellikle kötü bir uygulamadır çünkü eğer sıfır olursa uygulamanın çökmesine neden olur. Yalnızca kesinlikle gerekli olduğunda kullanın ve bunun yerine isteğe bağlı ciltlemeyi (veya başka herhangi bir "yumuşak" sarmayı açmayı) tercih edin
Antonio

81

Swift 5, bir dizi benzer nesneden bir dizi özellik değeri elde etmenin birçok yolunu sunar. İhtiyaçlarınıza göre, sorununuzu çözmek için aşağıdaki altı Oyun Alanı kod örneğinden birini seçebilirsiniz .


1. mapYöntemi kullanma

Swift ile Sequenceprotokole uyan türlerin bir map(_:)yöntemi vardır. Aşağıdaki örnek kod, nasıl kullanılacağını gösterir:

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. forDöngüyü kullanma

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. whileDöngüyü kullanma

Swift ile perde arkasında bir fordöngünün sadece bir yineleyicinin whileüzerindeki döngü olduğunu unutmayın sequence( daha fazla ayrıntı için bkz. 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. ve protokollere structuyan a kullanmaIteratorProtocolSequence

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. CollectionProtokol uzantısını kullanma veAnyIterator

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 ve kullanma NSArray'in value(forKeyPath:)yöntemi

Bu örneğin class Employeedevralmayı gerektirdiğini unutmayın 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]
}

5
çok büyük ... Olası yaklaşımların tam listesini anladığım kadarıyla
Injectios
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.