Notice
Recent Posts
Recent Comments
Link
관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] Set, Hashable 프로토콜 사용 방법 hash(into:) 본문

iOS 응용 (swift)

[iOS - swift] Set, Hashable 프로토콜 사용 방법 hash(into:)

jake-kim 2022. 3. 17. 22:54

* 해시의 기본 개념은 이전 포스팅 글 Hashable, 해시 참고

Hashable 사용 방법

  • 일반적으로 Hashable프로토콜을 따르면 스위프트의 기본 타입(String, Int, ...)등은 이미 적용
var nameSet = Set<String>()

self.nameSet.insert("jake")
self.nameSet.insert("jake")
print(self.nameSet) // ["jake"]
  • struct, enum, class와 같은 것들은 따로 hashValue를 정의해주지 않으면 해싱이 적용되지 않는 것을 주의
    • ex) id가 같으면 같은 사람으로 보고 싶지만, 아래처럼 age가 다르므로 set에 id가 같은 인스턴스가 중복으로 들어가는 케이스가 존재
struct Person: Hashable {
  var id: String
  var name: String
  var age: Int
}

self.personSet.insert(.init(id: "jake123", name: "jake", age: 10))
self.personSet.insert(.init(id: "jake123", name: "jake", age: 20))
print(self.personSet) // [ExText.Person(id: "jake123", name: "jake", age: 20), ExText.Person(id: "jake123", name: "jake", age: 10)]

-> hash function을 정의하여 id가 같으면 같은 케이스로 보도록 정의가 가능

hash function

  • Hashable 프로토콜에 선언된 메소드이고, hashValue를 정의하는 메소드

https://developer.apple.com/documentation/swift/hashable/2995575-hash

  • Hashable을 적용하려면 hashValue가 필요한데, 이 값을 hash(into:) 메소드와 == 메소드를 정의
struct Person: Hashable {
  var id: String
  var name: String
  var age: Int
  
  func hash(into hasher: inout Hasher) {
    hasher.combine(self.id.hashValue)
  }

  static func == (lhs: Self, rhs: Self) -> Bool {
    lhs.hashValue == rhs.hashValue
  }
}

self.personSet.insert(.init(id: "jake123", name: "jake", age: 10))
self.personSet.insert(.init(id: "jake123", name: "jake", age: 20))
print(self.personSet) // [ExText.Person(id: "jake123", name: "jake", age: 10)]

응용) enum에서 associatedValue 무시하고 case만 비교하는 Hashable 모델 정의

  • hash(into:) 메소드에서 switch - case 문으로 분기하여 hashValue 정의
enum ColorType: Hashable {
  case blue(CGFloat) // alpha
  case red(CGFloat) // alpha
  case green(CGFloat) // alpha
  
  func hash(into hasher: inout Hasher) {
    print(String(describing: self))
    switch self {
    case .blue:
      hasher.combine("blue".hashValue)
    case .red:
      hasher.combine("red".hashValue)
    case .green:
      hasher.combine("green".hashValue)
    }
  }

  static func == (lhs: Self, rhs: Self) -> Bool {
    lhs.hashValue == rhs.hashValue
  }
}

 

* 참고

https://developer.apple.com/documentation/swift/hashable/2995575-hash

Comments