2016-06-23 2 views
4

I는 다음과 같습니다 스위프트의 구조체가 : 지금에 맞도록 MapKey을 필요로하는 스위프트 사전의 핵심으로 MapKey을 사용할 필요가스위프트 : 사전 속성 해쉬 구조체

internal struct MapKey { 
    internal let id: String 
    internal let values: [String:String] 
} 
extension MapKey: Equatable {} 
func ==(lhs: MapKey, rhs: MapKey) -> Bool { 
    return lhs.id == rhs.id && lhs.values == rhs.values 
} 

을 Hashable 프로토콜.

Hashable의 올바른 구현은이 구조체에 대해 무엇이 될까요?

extension MapKey: Hashable { 
    var hashValue: Int { 
     return ??? // values does not have a hash function/property. 
    } 
} 

나는 몇 가지 연구를하고 있지만 나는 특성 자체에 대한 해시 값을 생성 할 수 있어야로, 사전을 해시하는 적절한 방법이 무엇인지 파악하는 데 실패했습니다. 어떤 도움이라도 대단히 감사합니다.

답변

3

전체 구조체를 사전 키로 사용해야하는 경우 데이터 모델을 검토해야한다고 생각합니다.

internal struct MapKey: Hashable { 
    internal let id: String 
    internal let values: [String:String] 

    var hashValue: Int { 
     get { 
      var hashString = self.id + ";" 
      for key in values.keys.sort() { 
       hashString += key + ";" + values[key]! 
      } 

      return hashString.hashValue 
     } 
    } 
} 

func ==(lhs: MapKey, rhs: MapKey) -> Bool { 
    return lhs.id == rhs.id && lhs.values == rhs.values 
} 

이것은 당신이 id 또는 키와 values의 값을 (;를) 세미콜론이없는 것으로 가정 : 어쨌든, 여기 한 가지 방법이다. HasableEquatable을 의미하므로 다시 선언하려면 Equatable을 준수 할 필요가 없습니다.

+2

해시가 고유 할 필요가 없으므로 세미콜론에 대한 어떠한 가정도하지 않아도됩니다 (이러한 구분 기호를 삽입 할 필요가 없습니다). –

+0

@MartinR과 동의합니다. 아이디어 코드를 보내 주셔서 감사합니다. 현재의 요구 사항을 해결하고, 데이터 모델을 검토하는 데 도움을 주시면 감사하겠습니다. – unbekant

+0

내가 틀렸다면 나를 바로 잡습니다. 이 대답을 읽고 (http://stackoverflow.com/a/31666711/5175709) 나는 ** 당신이 ** 별도로 Equatable을 구현해야한다고 생각한다. * – Honey

0

id와 값은 둘다 불변이므로 equals와 hashValue의 기본으로 사용할 수 있습니다. 그러나 MapKey.id (이름에서 다소 암시되는)가 MapKey를 고유하게 식별하는 경우 (최소한 사전 중 하나의 컨텍스트 내에서) == 연산자 인 MakKey.id를 사용하는 것이 더 쉽고 더 효율적입니다. hashValue뿐만 아니라

internal struct MapKey: Hashable { 
     internal let id: String 
     internal let values: [String:String] 

     var hashValue: Int { 
      get { return self.id.hashValue} 
     } 
    } 

    func ==(lhs: MapKey, rhs: MapKey) -> Bool { 
     return lhs.id == rhs.id 
    } 
+0

좋은 관찰 Eric. 불행히도 id가 내 생각에 고유하게 만드는 id + 값의 조합입니다. ID를 사용하면 다르게 생각할 수도 있습니다. 나는 내 모범을 위해 최선의 이름을 선택하지 않았을 수도있다. – unbekant