值可相等的字典序列的扩展
Extension for sequences of dictionaries where the values are Equatable
我尝试实现以下方法,通过比较字典的特定键来删除字典数组中的双条目。但是,由于错误,此扩展方法将不起作用:
Binary operator == cannot be applied to two 'Equatable' operands
这些显然是等同的且类型相同 (Iterator.Element.Value),为什么它不起作用?
我看到它将 Equatable 视为特定类型,而不是约束。我无法使其与通用类型一起使用或通过编写 where Iterator.Element == [String: Any], Iterator.Element.Value: Equatable
.
你们有解决这个问题的线索吗?
extension Sequence where Iterator.Element == [String: Equatable] {
public func removeDoubles(byKey uniqueKey: String) -> [Iterator.Element] {
var uniqueValues: [Iterator.Element.Value] = []
var noDoubles: [Iterator.Element] = []
for item in self {
if let itemValue = item[uniqueKey] {
if (uniqueValues.contains { element in
return itemValue == element
}) {
uniqueValues.append(itemValue)
noDoubles.append(item)
}
}
}
return noDoubles
}
}
A [String: Equatable]
是字符串到 any Equatable 类型的映射。不保证每个值都是 same 可等值类型。也就是说,实际上不可能创建这样的字典(因为 Equatable
有一个关联类型),所以这个扩展不能应用于 Swift 中的任何实际类型。 (事实上你在这里没有收到错误是 IMO 编译器中的错误。)
完成这项工作所需的功能是 SE-0142,它已被接受,但未实现。您目前不能以这种方式基于类型约束来约束扩展。
有很多方法可以实现您想要做的事情。一种直接的方法是传递相等函数:
extension Sequence {
public func removeDoubles(with equal: (Iterator.Element, Iterator.Element) -> Bool) -> [Iterator.Element] {
var noDoubles: [Iterator.Element] = []
for item in self {
if !noDoubles.contains(where: { equal([=10=], item) }) {
noDoubles.append(item)
}
}
return noDoubles
}
}
let noDupes = dict.removeDoubles(with: { [=10=]["name"] == ["name"] })
这与您的代码在缺少 name
时的行为方式略有不同,但稍作调整就可以获得您想要的结果。
也就是说,对此的需求强烈表明数据模型不正确。如果你有这个字典序列,并且你正试图在它的基础上构建一个扩展,你几乎肯定想要有一个结构序列。那么这就变得更直接了。字典的要点是键到值的任意映射。如果您有一小组合法的已知密钥,那确实是一个结构。
我尝试实现以下方法,通过比较字典的特定键来删除字典数组中的双条目。但是,由于错误,此扩展方法将不起作用:
Binary operator == cannot be applied to two 'Equatable' operands
这些显然是等同的且类型相同 (Iterator.Element.Value),为什么它不起作用?
我看到它将 Equatable 视为特定类型,而不是约束。我无法使其与通用类型一起使用或通过编写 where Iterator.Element == [String: Any], Iterator.Element.Value: Equatable
.
你们有解决这个问题的线索吗?
extension Sequence where Iterator.Element == [String: Equatable] {
public func removeDoubles(byKey uniqueKey: String) -> [Iterator.Element] {
var uniqueValues: [Iterator.Element.Value] = []
var noDoubles: [Iterator.Element] = []
for item in self {
if let itemValue = item[uniqueKey] {
if (uniqueValues.contains { element in
return itemValue == element
}) {
uniqueValues.append(itemValue)
noDoubles.append(item)
}
}
}
return noDoubles
}
}
A [String: Equatable]
是字符串到 any Equatable 类型的映射。不保证每个值都是 same 可等值类型。也就是说,实际上不可能创建这样的字典(因为 Equatable
有一个关联类型),所以这个扩展不能应用于 Swift 中的任何实际类型。 (事实上你在这里没有收到错误是 IMO 编译器中的错误。)
完成这项工作所需的功能是 SE-0142,它已被接受,但未实现。您目前不能以这种方式基于类型约束来约束扩展。
有很多方法可以实现您想要做的事情。一种直接的方法是传递相等函数:
extension Sequence {
public func removeDoubles(with equal: (Iterator.Element, Iterator.Element) -> Bool) -> [Iterator.Element] {
var noDoubles: [Iterator.Element] = []
for item in self {
if !noDoubles.contains(where: { equal([=10=], item) }) {
noDoubles.append(item)
}
}
return noDoubles
}
}
let noDupes = dict.removeDoubles(with: { [=10=]["name"] == ["name"] })
这与您的代码在缺少 name
时的行为方式略有不同,但稍作调整就可以获得您想要的结果。
也就是说,对此的需求强烈表明数据模型不正确。如果你有这个字典序列,并且你正试图在它的基础上构建一个扩展,你几乎肯定想要有一个结构序列。那么这就变得更直接了。字典的要点是键到值的任意映射。如果您有一小组合法的已知密钥,那确实是一个结构。