2017-02-27 12 views
0

특정 키를 비교하여 사전 배열에서 이중 항목을 제거하려면 다음 방법을 구현하려고했습니다. 그러나,이 확장 방법에 의한 오류로 작동하지 않습니다값이 같은 사전의 순서에 대한 확장

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

이 분명히 있습니다 equatable 및 (Iterator.Element.Value) 같은 종류의, 그래서 왜 작동하지 않는 이유는 무엇입니까?

저는 Equatable을 제약이 아닌 특정 유형으로 취급한다는 것을 알고 있습니다. 일반 유형이나 where Iterator.Element == [String: Any], Iterator.Element.Value: Equatable을 작성하여 작동하게 만들 수 없습니다.

여러분은이 문제를 해결하는 방법에 대한 단서가 있습니까? [String: 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

어떤 Equatable 유형 문자열의 매핑입니다. 각 값이 동일 동등한 유형이라는 약속은 없습니다. 즉, Equatable에는 연결된 유형이 있으므로 사전을 만들 수는 없으므로이 확장 프로그램은 Swift의 실제 유형에는 적용 할 수 없습니다. (여기서 오류가 발생하지 않는다는 사실은 컴파일러의 IMO 버그입니다.)

이 작업을 수행해야하는 기능은 수락되었지만 구현되지 않은 SE-0142입니다. 현재는 유형 제약 조건을 기반으로 확장을 이런 식으로 제한 할 수 없습니다.

당신이하려는 것을 달성하는 데는 여러 가지 방법이 있습니다. 이 name이 누락 될 때의 동작을에서 코드보다 약간 다르지만, 약간의 개조하면 되겠 얻을 수

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"] }) 

당신이 원하는 : 한 가지 간단한 방법은 평등 기능을 전달하는 것입니다.

즉,이 문제에 대한 필요성은 잘못된 데이터 모델을 강력히 시사합니다. 만약 당신이 사전의 순서를 가지고 있고, 그것에 확장을 만들려고한다면, 당신은 거의 확실하게 구조체들의 시퀀스를 가지게 될 것입니다. 그러면 이것은 더 직설적이됩니다. 사전의 핵심은 키와 값의 임의 맵핑입니다. 합법적 인 작은 알려진 키 세트가 있다면 실제로 구조체입니다.

+0

SE-0142가 어떻게 도움이 될지 모르겠다. [매개 변수가있는 확장] (https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#parameterized-extensions)을 의미한다고 생각하십니까? :) – Hamish

+0

나는 매개 변수가있는 확장을 의미하지만, SE-0142가 제공 했더라도. 아마 잘못 읽었을 것입니다. 1422. –

+0

도와 줘서 고맙습니다. 문제는 이것들이 모두 JSON이며 서버의 로컬과 원격을 병합해야한다는 것입니다. 병합 후에는 Core Data에 저장되며 다른 구조체 유형을 만드는 데 많은 과도한 작업이 필요합니다. NSManagedObjects이므로 삽입하기 전에 사용할 수 없습니다. 메모리 컨텍스트에서 이들 모두를 저장하고 비교하는 것은 너무 단순한 것처럼 보였습니다. 그래서이 확장에 대한 시도를 계속했습니다. – Suryu