객체 배열에서 속성 값 배열 가져 오기


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객체 의 배열을 가지고 있습니다. 지금 필요한 것은id 해당 배열에있는 모든 객체 s를 새 배열로 입니다.

나는 또한 이것을 발견했다 질문을 했다 . 하지만 Objective-C에 있으므로valueForKeyPath 달성하기 위해 사용하고 있습니다.

Swift에서 어떻게 할 수 있습니까?

답변:


234

당신이 사용할 수있는 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변환 합니다. 이는 "모든 인스턴스에서 id 필드를 추출하여 배열에 넣습니다 "라고 말하는 것과 같습니다.EmployeeIntidEmployee
Antonio

4
@ Isuru,이 대답은 정확히 원하는 것을합니다. s 의 배열에서 ids모든 id값으로 호출되는 새 배열을 만듭니다 Employee. 원래 배열은 그대로 유지됩니다.
vacawama

2
Swift 2 베타에서 올바른 구문은 다음과 같습니다array.map( { $0.id })
TotoroTotoro 2015-08-26

10
옵션을 사용하는 경우 확인하십시오! 그것. 시간이 걸렸습니다.
Chris

2
@Chris 강제 언 래핑은 일반적으로 나쁜 습관입니다. nil이면 앱이 중단되기 때문입니다. 엄격하게 필요한 경우에만 사용하고 대신 선택적 바인딩 (또는 다른 "소프트"언 래핑)을 선호합니다.
Antonio

81

Swift 5는 유사한 객체의 배열에서 속성 값 배열을 가져 오는 다양한 방법을 제공합니다. 필요에 따라 다음 6 가지 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루프 일뿐 입니다 (자세한 내용 sequenceIteratorProtocol 참조).

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을 준수하는 사용IteratorProtocolSequence

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 및 NSArrayvalue(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]
}

5
엄청나게 ... 그것은 내가 이해할 수있는 완전한 가능한 접근 방식 목록
Injectios
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.