Количество элементов в массиве с определенным значением свойства

У меня есть класс Person():

class Person : NSObject {

    var firstName : String
    var lastName : String
    var imageFor : UIImage?
    var isManager : Bool?

    init (firstName : String, lastName: String, isManager : Bool) {
        self.firstName = firstName
        self.lastName = lastName
        self.isManager = isManager
    }
}

У меня есть массив Person()

var peopleArray = [Person]()

Я хочу подсчитать количество людей в массиве, у которых

 isManager: true

Я чувствую, что это там, но я не могу найти его или найти параметры поиска.

Спасибо.

Ответ 1

Использовать метод filter:

let managersCount = peopleArray.filter { (person : Person) -> Bool in
    return person.isManager!
}.count

или даже проще:

let moreCount = peopleArray.filter{ $0.isManager! }.count

Ответ 2

Вы можете использовать reduce следующим образом:

let count = peopleArray.reduce(0, combine: { (count: Int, instance: Person) -> Int in
    return count + (instance.isManager! ? 1 : 0) }
)

или более компактная версия:

let count = peopleArray.reduce(0) { $0 + ($1.isManager! ? 1 : 0) }

reduce применяет замыкание (2-й параметр) к каждому элементу массива, передавая значение, полученное для предыдущего элемента (или начальное значение, которое является значением 0, переданным как его первый параметр), и текущим элемент массива. В закрытии вы возвращаете count плюс ноль или один, в зависимости от того, является ли свойство isManager true или нет.

Подробнее о reduce и filter в стандартная ссылка на библиотеку

Ответ 3

В Swift 5 вы можете использовать метод Array count(where:) если хотите подсчитать количество элементов массива, которые соответствуют заданному предикату. count(where:) имеет следующую декларацию:

func count(where predicate: (Element) throws -> Bool) rethrows -> Int

Возвращает количество элементов в последовательности, которые удовлетворяют данному предикату.


Следующий код Playground показывает, как использовать count(where:):

struct Person {

    var name: String
    var isManager: Bool

    init (name: String, isManager: Bool) {
        self.name = name
        self.isManager = isManager
    }

}

let array = [
    Person(name: "Jane", isManager: true),
    Person(name: "Bob", isManager: false),
    Person(name: "Joe", isManager: true),
    Person(name: "Jill", isManager: true),
    Person(name: "Ted", isManager: false)
]

let managerCount = array.count(where: { (person: Person) -> Bool in
    person.isManager == true
})
// let managerCount = array.count { $0.isManager } // also works

print(managerCount) // prints: 3