iOS Swit 3 - 过滤器内的过滤器阵列

iOS Swit 3 - filter array inside filter

我想在过滤器中过滤数组。首先,我有一大堆 Staff 对象 (self.bookingSettings.staffs)。在这个数组中,我有多个这样的对象:

"staffs": [
    {
        "id": 1,
        "name": "Brian",
        "services": [
            {
                "id": 1
            },
            {
                "id": 2
            },
            {
                "id": 3
            },
            {
                "id": 4
            }
        ],
        "pos": 1
    },...

我想过滤这个数组,以便只提供 id = 3 的服务。

如果第一个对象等于 3,我成功拥有此代码:

self.bookingSettings.staffs.filter({ [=12=].services.first?.id == self.bookingService.id })

但这只需要第一项。

我想我必须在我的过滤器函数中进行过滤,像这样循环遍历服务中的所有对象:

self.bookingSettings.staffs.filter({ [=13=].services.filter({ [=13=].id == self.bookingService.id }) })

但出现以下错误:Cannot convert value of type [BookingService] to closure result type Bool.

这是个好主意吗?我怎样才能做到这一点?

可以使用filter,它看起来像这样:

self.bookingSettings.staffs.filter {
    ![=10=].services.filter{ [=10=].id == self.bookingService.id }.isEmpty
}

这段代码正在构建一个完整的过滤结果数组,只检查它是否为空并立即丢弃它。由于筛选 returns all 与列表中的谓词匹配的项目,它在找到匹配项后不会停止(这正是您要查找的)。因此,即使一百万个元素列表中的第一个元素匹配,它仍会继续检查另外 999,999 个元素。如果其他 999,999 个元素也匹配,那么它们将 all 复制到 filter 的结果中。这很愚蠢,在这种情况下可以使用比必要更多的 CPU 和 RAM。

你只需要contains(where:):

self.bookingSettings.staffs.filter {
    [=11=].services.contains(where: { [=11=].id == self.bookingService.id })
}

contains(where:) 短路,意味着它不会在找到匹配后继续检查元素。一旦找到匹配项,它就会停止并且 returns 为真。它也不会同时将匹配元素复制到新列表中。