我有两个收藏集(例如Set
和Array
)。每个都有Object/Struct
不同的类型,但都有一些primary key
。
struct A {
var name: String
var primaryID: Int
}
class B {
var kind: String
var primaryID: Int
}
我有这些收藏品:
var setOfA: Set<A>
var arrayOfB: Array<B>
我需要使用arrayOfB
的值更新setOfA
。例如,遍历arrayOfB
,从setOfA
(其中primaryID相等)获取元素并更新arrayOfB
。
看起来像:
for bElement in arrayOfB {
let a = setOfA.first(where: { $0.primaryID == bElement.primaryID })
bElement.kind = a.name // Just an example
}
如果first(where:)
的效率是O(n)(我真的不知道),上面的代码是O(n ^ 2)(假设两个集合长度相同)。
我能想到的一件事就是删除set
我获取的每个元素,将内循环减少一半。
有更好的方法吗?
答案 0 :(得分:1)
是的,first(where:)
遍历集合直到匹配
找到元素,因此您的方法的复杂性受到限制
product 数组元素和集合的数量。
这就是我要做的事情:首先创建一个字典,然后映射每个字典
来自setOfA
的对应元素的主要ID:
var idToA: [Int: A] = [:]
for a in setOfA {
idToA[a.primaryID] = a
}
然后遍历arrayOfB
,在字典中查找id,然后更新
必要时的元素:
for b in arrayOfB {
if let a = idToA[b.primaryID] {
b.kind = a.name
}
}
这需要对setOfA
和arrayOfB
进行单次遍历,
加上字典查找。 (如果,字典查找很快
关键哈希值上几乎没有碰撞,情况就是如此
整数键。)