รับอาร์เรย์ของค่าคุณสมบัติจากอาร์เรย์อ็อบเจ็กต์


113

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วัตถุ สิ่งที่ฉันต้องการตอนนี้คือการแยกids ของวัตถุทั้งหมดในอาร์เรย์นั้นลงในอาร์เรย์ใหม่

ฉันยังพบคำถามที่คล้ายกันนี้ แต่มันอยู่ใน Objective-C ดังนั้นจึงใช้valueForKeyPathเพื่อทำสิ่งนี้ให้สำเร็จ

ฉันจะทำสิ่งนี้ใน Swift ได้อย่างไร

คำตอบ:


235

คุณสามารถใช้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 }

1
นั่นคือสิ่งที่mapทำ - มันจะแปลงอาร์เรย์ของEmployeeอาร์เรย์ที่Intเต็มไปด้วยidฟิลด์ ซึ่งเทียบเท่ากับการพูดว่า "แยกฟิลด์ id จากอินสแตนซ์ทั้งหมดEmployeeและใส่ลงในอาร์เรย์"
อันโตนิโอ

4
@ อิซึรุคำตอบนี้ตอบโจทย์สิ่งที่คุณต้องการ สร้างอาร์เรย์ใหม่ที่เรียกว่าค่าidsทั้งหมดidจากอาร์เรย์ของEmployees โปรดทราบว่าจะทำให้อาร์เรย์เดิมไม่เสียหาย
vacawama

2
ดูเหมือนว่าใน Swift 2 beta ไวยากรณ์ที่ถูกต้องจะเป็นarray.map( { $0.id })
TotoroTotoro

10
หากคุณใช้อุปกรณ์เสริมอย่าลืม! มัน. ใช้เวลาหลายชั่วโมง
คริส

2
@Chris บังคับให้แกะโดยปกติจะเป็นการปฏิบัติที่ไม่ดีเพราะถ้าไม่มีมันจะทำให้แอปขัดข้อง ใช้เฉพาะเมื่อจำเป็นอย่างเคร่งครัดและชอบการผูกเสริม (หรือการแกะแบบ "นุ่ม ๆ " อื่น ๆ ) แทน
อันโตนิโอ

81

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วนซ้ำเป็นเพียงการwhileวนซ้ำบนตัว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. การใช้สิ่งstructที่เป็นไปตาม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's value(forKeyPath:)วิธี

หมายเหตุว่าตัวอย่างนี้ต้องมีการสืบทอดมาจากclass EmployeeNSObject

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
ใหญ่มาก ... เท่าที่ฉันเข้าใจรายการแนวทางที่เป็นไปได้ทั้งหมด
Injectios
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.