filter(_ :)。first和first(where :)之间有什么区别?

时间:2017-10-18 11:13:49

标签: arrays swift big-o

请考虑以下字符串数组:

let strings = ["str1", "str2", "str10", "str20"]

让我们假设所需要的是获取包含5个字符的第一个元素(String),我可以使用filter(_:)获取它,如下所示:

let filterString = strings.filter { $0.count == 5 }.first
print(filterString!) // str10

但在审核first(where:)方法后,我意识到我将能够获得相同的输出:

let firstWhereString = strings.first(where: { $0.count == 5 })
print(firstWhereString!) // str10

那么使用一个而不是另一个有什么好处?只是filter(_:)返回一个序列而first(where:)返回一个元素?

更新

我注意到过滤器(_ :)花了 5次来完成这样的过程,而第一次(其中:)花了 4次

enter image description here

2 个答案:

答案 0 :(得分:5)

您认为filter(_:)返回满足谓词的所有元素并且first(where:)返回满足谓词的 first 元素是正确的。

所以,这给我们留下了一个更有趣的问题:elements.filter(predicate).firstelements.first(where: predicate)之间的区别 elements.filter(predicate).first

正如您已经注意到他们最终都得到了相同的结果。不同之处在于他们的“评估策略”。致电:

elements.first(where: predicate)

将“急切地”检查所有元素的谓词以过滤完整的元素列表,然后从过滤器列表中选择第一个元素。相比之下,请致电:

map

将“懒惰地”检查元素的谓词,直到找到满足谓词的谓词,然后返回该元素。

作为第三种选择,您可以明确地使用“提供[列表]的视图来提供通常急切操作的延迟实现,例如filterelements.lazy.filter(predicate).first ”:

elements.lazy.filter(predicate)

这会将评估策略更改为“懒惰”。实际上,只是调用first而不会检查任何元素的谓词是非常懒惰的。只有在这个惰性视图中“急切地”评估first(where:)元素时,它才会评估足够的元素以返回一个结果。

除了这些替代方案之间的任何技术差异之外,我会说你应该使用最明确描述你的意图的那个。如果您正在寻找与条件/谓词匹配的第一个元素,那么{{1}}最好地传达 intent

答案 1 :(得分:2)

我认为我们应该从分别考虑每种方法及其目的开始。

filter(_:)并非专门用于准备我们获取first元素。这是关于过滤,就是这样。它只是给我们一个序列。 first之后可以使用filter,但这只是一个使用实例,可能是一个案例。 first被称为集合,如果我们想要,我们当然可以在filter之后直接使用它。

但是first(where:) 设计filter and return单个元素,显然是完成这种任务的首选方法。也就是说,从性能角度来看,很容易推测它也是首选。如上所述,我们filter整个序列,但first(where:)我们只处理序列的一部分,直到满足条件。

相关问题