来自集合的匹配元素,不同类型,公共元素

时间:2018-05-05 08:58:33

标签: swift performance

我有两个收藏集(例如SetArray)。每个都有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我获取的每个元素,将内循环减少一半。

有更好的方法吗?

1 个答案:

答案 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
    }
}

这需要对setOfAarrayOfB进行单次遍历, 加上字典查找。 (如果,字典查找很快 关键哈希值上几乎没有碰撞,情况就是如此 整数键。)