2017-02-27 28 views
0

我试图通过比较它们的特定键来实现以下方法来删除字典数组中的重复条目。然而,这种扩展方法是行不通的,由于错误:对值为可Equatable的字典序列的扩展

Binary operator == cannot be applied to two 'Equatable' operands

这些显然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 
    } 
} 

回答

0

[String: Equatable]是串到任何 Equatable类型的映射。没有承诺每个值都是相同的等值类型。也就是说,创建这样的字典实际上是不可能的(因为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缺少它如何表现你的代码略有不同,但轻微的调整可以得到你想要的东西。

也就是说,这个需求强烈地暗示了一个不正确的数据模型。如果你有这个序列的字典,并且你正在试图构建一个扩展,那么你几乎肯定意味着要有一系列的结构。然后这变得更直接。字典的要点是键与值的任意映射。如果你有一组合法的已知键,那真是一个结构。

+0

不知道SE-0142如何帮助这里,我想你的意思是[参数化扩展](https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#parameterized-extensions)? :) – Hamish

+0

我的意思是参数化扩展,但我虽然SE-0142规定。可能误读了142. –

+0

谢谢你的帮助。问题是这些都是JSON,我需要合并来自服务器的两个 - 本地和远程两个。合并后它被保存到核心数据,并且它看起来像创建另一个结构类型过多的工作,因为这些是NSManagedObjects,所以我不能在插入它们之前使用它们。在内存环境中,将它们存储和比较看起来对于这个简单的目的来说太多了,所以我继续尝试这个扩展。 – Suryu