Ahm*_*d F 1 arrays big-o swift
请考虑以下字符串数组:
let strings = ["str1", "str2", "str10", "str20"]
Run Code Online (Sandbox Code Playgroud)
让我们假设需要的是获取包含5个字符的第一个元素(String),我可以通过使用filter(_:)如下来获得它:
let filterString = strings.filter { $0.count == 5 }.first
print(filterString!) // str10
Run Code Online (Sandbox Code Playgroud)
但在审查了该first(where:)方法后,我意识到我将能够得到相同的输出:
let firstWhereString = strings.first(where: { $0.count == 5 })
print(firstWhereString!) // str10
Run Code Online (Sandbox Code Playgroud)
那么使用一个而不是另一个的好处是什么?只是filter(_:)返回一个序列并first(where:)返回一个元素?
更新:
我注意到过滤器(_ :)花了5次做这样的过程,而第一次(其中:)花了4次:
你在观察中是正确的,它filter(_:)返回所有满足谓词的元素,并first(where:)返回满足谓词的第一个元素.
所以,这留给我们的区别是什么之间的更有趣的问题elements.filter(predicate).first和
elements.first(where: predicate).
正如你已经注意到他们都得到了相同的结果.不同之处在于他们的"评估策略".呼叫:
elements.filter(predicate).first
Run Code Online (Sandbox Code Playgroud)
将"急切地"检查所有元素的谓词以过滤完整的元素列表,然后从过滤器列表中选择第一个元素.相比之下,致电:
elements.first(where: predicate)
Run Code Online (Sandbox Code Playgroud)
将"懒惰地"检查对元素的谓词,直到找到满足谓词的谓词,然后返回该元素.
作为第三种选择,您可以明确地使用"一个视图到[列表],提供通常渴望操作的延迟实现,例如map和filter":
elements.lazy.filter(predicate).first
Run Code Online (Sandbox Code Playgroud)
这将评估策略变为"懒惰".事实上,它是如此懒惰,只是调用elements.lazy.filter(predicate)不会检查任何元素的谓词.只有当first在这个惰性视图上"热切地"评估元素时,它才会评估足够的元素以返回一个结果.
除了这些替代方案之间的任何技术差异,我会说你应该使用最明确描述你的意图的那个.如果您正在寻找与条件/谓词匹配的第一个元素,那么最好地first(where:)传达该意图.