值是 Equatable 的字典序列的扩展

Posted

技术标签:

【中文标题】值是 Equatable 的字典序列的扩展【英文标题】:Extension for sequences of dictionaries where the values are Equatable 【发布时间】:2017-02-27 15:14:18 【问题描述】:

我尝试实现以下方法,通过比较字典数组的特定键来删除字典数组中的双重条目。但是,由于错误,此扩展方法将不起作用:

二元运算符 == 不能应用于两个 'Equatable' 操作数

这些显然是等价的并且是相同的类型(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
    

【问题讨论】:

【参考方案1】:

[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($0, item) ) 
                noDoubles.append(item)
            
        
        return noDoubles
    


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

这与您的代码在缺少name 时的行为方式略有不同,但稍作调整可能会得到您想要的。

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

【讨论】:

不确定 SE-0142 在这里有什么帮助,我想你的意思是 Parameterized extensions? :) 我的意思是参数化扩展,但我认为 SE-0142 提供了这一点。可能误读了 142。 感谢您的帮助。问题是这些都是 JSON,我需要合并其中的两个 - 一个本地的和一个来自服务器的远程的。合并后它被保存到核心数据中,创建另一个结构类型似乎需要做太多的工作,因为这些是 NSManagedObjects,所以在插入它们之前我不能使用它们。在内存上下文中,将它们全部存储并比较对于这个简单的目的来说似乎太多了,所以我继续尝试这个扩展。

以上是关于值是 Equatable 的字典序列的扩展的主要内容,如果未能解决你的问题,请参考以下文章

序列化包含字典成员的类

面试:字符串字典序最大的子序列

《转》python学习字典

51nod 1255 字典序最小的子序列

51Nod1255 字典序最小的子序列

leetcode31 下一个排列 字典序