我想在过滤器中过滤数组。首先,我有一个很大的Staff对象数组(self.bookingSettings.staffs)。在这个数组中,我有多个像这样的对象:
<div id="container">
<div class="different_class">Test</div>
<div class="child">Test</div>
<div class="child">Test</div>
<div class="child">Test</div>
<div class="child">Test</div>
</div>
我想过滤此数组,以便只使用"staffs": [
{
"id": 1,
"name": "Brian",
"services": [
{
"id": 1
},
{
"id": 2
},
{
"id": 3
},
{
"id": 4
}
],
"pos": 1
},...
。
如果使用此代码,第一个对象等于id = 3
,我就成功了:
3
但只占第一项。
我想我必须在我的过滤器函数中进行过滤,这样就可以遍历服务中的所有对象:
self.bookingSettings.staffs.filter({ $0.services.first?.id == self.bookingService.id })
但我发现了以下错误:self.bookingSettings.staffs.filter({ $0.services.filter({ $0.id == self.bookingService.id }) })
这是个好主意吗?我怎样才能做到这一点?
答案 0 :(得分:4)
你可以使用filter
,它看起来像这样:
self.bookingSettings.staffs.filter {
!$0.services.filter{ $0.id == self.bookingService.id }.isEmpty
}
此代码构建整个过滤结果数组,仅检查其是否为空并立即丢弃它。由于过滤器返回与列表中的谓词匹配的所有项,因此在找到匹配项后(它实际上是您正在寻找的)不会停止。因此,即使一百万个元素列表中的第一个元素匹配,它仍然会继续检查999,999个元素。如果其他999,999元素也匹配,那么它们将 all 复制到filter
的结果中。这很愚蠢,在这种情况下可以使用比所需更多的CPU和RAM。
您只需要contains(where:)
:
self.bookingSettings.staffs.filter {
$0.services.contains(where: { $0.id == self.bookingService.id })
}
contains(where:)
短路,意味着在找到匹配后不会继续检查元素。一旦找到匹配,它就会停止并返回true。它也不会将匹配元素复制到新列表中。