swift - Swift 的自定义比较器
问题描述
这是我的代码(简化代码):
struct SomeStruct {
let id: Int
let age: Int
}
extension SomeStruct: Hashable {
var hashValue: Int {
return id.hashValue * age.hashValue
}
static func ==(lhs: SomeStruct, rhs: SomeStruct) -> Bool {
return lhs.id == rhs.id && lhs.age == rhs.age
}
}
struct Calculator {
let struct1: [SomeStruct]
let struct2: [SomeStruct]
func uniqueById() {
let struct3 = Set(struct2).union(Set(struct1))
// I want to union it by property 'id' only.
// If the property 'id' is equal for both objects,
// the object in struct2 should be used (since that can have a different age property)
}
}
SomeStruct
是生成的struct
,我不想编辑。我想创建一个基于 1 个属性的Set
for :. 为此,我认为我需要一个自定义的. 有什么快速的方法吗?这是我唯一能想到的,但我想知道是否有更好的方法:SomeStruct
id
Comparator
struct SomeStructComparatorById: Hashable {
let someStruct: SomeStruct
var hashValue: Int {
return someStruct.id.hashValue
}
static func ==(lhs: SomeStructComparatorById, rhs: SomeStructComparatorById) -> Bool {
return lhs.someStruct.id == rhs.someStruct.id
}
}
解决方案
首先,我认为这在 Java 中行不通。addAll()
不带比较器(也不带contains
等)比较器用于排序,而不是相等。从概念上讲,这打破了 Set 在任何语言中的工作方式。两个项目不是“相等的”,除非它们在所有情况下都可以交换。
这告诉我们我们不想要一个 Set 这里。您在这里想要的是基于某些键的唯一性。那是一本字典(正如丹尼尔所讨论的那样)。
您可以将“id -> age”字典或“id -> struct-of-other-properties”字典作为主要数据类型(而不是使用数组)。或者您可以将您的数组变成一个临时字典,如下所示:
extension Dictionary {
init<S>(_ values: S, uniquelyKeyedBy keyPath: KeyPath<S.Element, Key>)
where S : Sequence, S.Element == Value {
let keys = values.map { $0[keyPath: keyPath] }
self.init(uniqueKeysWithValues: zip(keys, values))
}
}
并像这样合并它们:
let dict1 = Dictionary(struct1, uniquelyKeyedBy: \.id)
let dict2 = Dictionary(struct2, uniquelyKeyedBy: \.id)
let merged = dict1.merging(dict2, uniquingKeysWith: { old, new in old }).values
这留下merged
了[SomeStruct]
。
请注意,这Dictionary(uniquelyKeyedBy:)
与 具有相同的先决条件Dictionary(uniqueKeysWithValues:)
。如果有重复的键,这是一个编程错误,会引发前置条件失败。
推荐阅读
- java - 与 Java SendMail 相比,VB.NET SmtpClient API 是否受到限制?
- python - 除了最终结果之外,如何获取“reduce”的所有中间值?
- java - 将自定义配置器与 WebSocket 一起使用
- python - 将丑陋的字符串(自定义非 json 格式)转换为字典
- python - 如何通过多维数组优化循环?
- jquery - jQuery click 事件在 iPhone 浏览器上不起作用(已经尝试过 cursor:pointer;)
- python - Tkinter - 我可以在不干扰的情况下使用多个后功能吗?
- python - 如何修复 Python 中的“TypeError:字符串索引必须是整数”错误
- python - 如何制作一个在矩阵内绘制弧线的函数?
- smb - 使用 SmbLibraryStd 访问 SMB1/2 时出现问题