swift - 字典序列的扩展,其中值是 Equatable

标签 swift sequence extension-methods 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
    }
}

最佳答案

[String: E​​quatable] 是字符串到任何 Equatable 类型的映射。不保证每个值都是相同的可等类型。也就是说,实际上不可能创建这样的字典(因为 Equatable 有关联的类型),因此此扩展不能应用于 Swift 中的任何实际类型。 (事实上​​,在我看来,您在这里没有收到错误是编译器中的一个错误。)

完成这项工作所需的功能是 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($0, item) }) {
                noDoubles.append(item)
            }
        }
        return noDoubles
    }
}

let noDupes = dict.removeDoubles(with: { $0["name"] == $1["name"] })

这与您的代码在缺少 name 时的行为方式略有不同,但稍加调整就可以获得您想要的结果。

也就是说,这种需求强烈表明数据模型不正确。如果你有这个字典序列,并且你试图在其上构建一个扩展,那么你几乎肯定意味着有一个结构序列。那么这就变得更加简单了。字典的要点是键到值的任意映射。如果您有一小组已知的合法 key ,那么这实际上是一个结构。

关于swift - 字典序列的扩展,其中值是 Equatable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42489232/

相关文章:

ios - SKAction.removeFromParent 不要用 SKAction.repeatActionForever 删除 Sprite

ios - 如何在 Swift 4 中基于字典的键名添加数组

postgresql - 自动递增,但忽略列中的现有值

c# - 使用泛型的扩展方法

generics - 如何在 Kotlin 中编写通用扩展方法?

.net - 在 .Net 中链接方法的正确方法是什么

ios - CosmicMind Swift Material 库程序化自动布局与堆叠菜单

ios - Swift/如何根据屏幕尺寸更改自动约束值

list - 子序列的推理规则

javascript - 来自较早 promise 的控制台日志出现在来自最新 promise 的控制台日志之后