gpt4 book ai didi

swift - 字段子集的集合差异

转载 作者:行者123 更新时间:2023-11-30 10:31:37 25 4
gpt4 key购买 nike

考虑以下代码片段,它创建 2 个 Foo 结构集合的差异

struct Foo {

let v: String
let other: Int
}

extension Foo: Hashable {

func hash(into hasher: inout Hasher) {
hasher.combine(v)
}
}

extension Foo: CustomStringConvertible {

var description: String {
return v
}
}

var col1 = [
Foo(v: "a", other: 1),
Foo(v: "b", other: 1),
Foo(v: "c", other: 1),
]

var col2 = [
Foo(v: "a", other: 1),
Foo(v: "c", other: 1),
Foo(v: "d", other: 1),
]

let diff = col2.difference(from: col1)

diff.forEach { change in
switch change {
case let .remove(offset, _, _):
print("remove: \(offset)")
case let .insert(offset, _, _):
print("insert: \(offset)")
}
}

这将按预期产生以下print输出:

remove: 1
insert: 2

现在将 col2other 字段更改为 2,如下所示

var col2 = [
Foo(v: "a", other: 2),
Foo(v: "c", other: 2),
Foo(v: "d", other: 2),
]

由于我仅从 v 生成哈希值,因此我期望得到相同的输出,但我实际得到的是这个。

remove: 2
remove: 1
remove: 0
insert: 0
insert: 1
insert: 2

我在这里缺少什么?

最佳答案

BidirectionalCollection.difference(from:)根据两个集合元素的相等来计算它们的“差异”。由于您没有为 Foo 实现 ==,编译器会合成一个默认实现,并比较所有(存储的)属性。

采用Hashable协议(protocol)可以提高性能,但不影响值的相等性:不同的元素可以具有相同的哈希值。

如果您提供我们自己的 Equatable 实现为

extension Foo: Equatable {
static func ==(lhs: Foo, rhs: Foo) -> Bool {
return lhs.v == rhs.v
}
}

然后

Foo(v: "a", other: 1) == Foo(v: "a", other: 2) // etc.

输出是预期的

remove: 1
insert: 2

或者,使用``BidirectionalCollection.difference(from:by:)`并通过自定义等效测试:

let diff = col2.difference(from: col1, by: { $0.v == $1.v })

关于swift - 字段子集的集合差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59086741/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com