在集合上执行包含是否会使惰性映射变得多余



假设我有以下

let ids = mySet.lazy.map { $0.id }
ids.contains(...)

.contains()功能是否使lazy冗余?我假设它必须在整个mySet上执行map才能执行contains()?还是我错了?

你错了。

添加.lazy会导致映射返回LazyMapSequence而不是Array。当您在此LazyMapSequence上调用.contains时,它将在.contains检查每个元素时对其执行映射操作。

想象一下,你的套装有100件商品。.contains在找到您要搜索的项目后立即退出,因此,如果您运气好,并且Set中的第一个项目满足.contains,则只有该项目会被.mapped,.contains会立即返回true

请注意,Set是无序的,因此搜索的顺序是未指定的。

在操场上试试这个:

struct Person : Hashable {
var id: Int
var name: String
}
let mySet = Set([Person(id: 1, name: "Joe"),
Person(id: 2, name: "Abhijit"),
Person(id: 3, name: "Fred")])
let ids = mySet.lazy.map { (person) -> Int in print("mapped (person)"); return person.id }
print(ids.contains(1))

观察输出。当我尝试它时,我得到了:

mapped Person(id: 1, name: "Joe")
true

然后删除.lazy并再次运行它。我得到了:

mapped Person(id: 1, name: "Joe")
mapped Person(id: 3, name: "Fred")
mapped Person(id: 2, name: "Abhijit")
true

因此.lazy无需在每个项目上运行.map。如果.contains找到了它要查找的内容,那么就没有必要对每个项目运行.map

注意:如果Set中不包含您正在搜索的项目,则在.contains返回false之前,每个项目都将被访问和.mapped。


现在如果包含被称为多时间?是否必须再次从"未映射"序列开始?或它会把以前映射的值存储在某个地方吗?

lazy的第二个效果是没有使用任何存储来保存中间映射值。因此,多次调用contains将对访问的每个设置值再次执行映射操作。

最新更新