ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Swift Generic - 3
    Programming/Swift(iOS) 2021. 4. 6. 21:28
    728x90

    String 배열의 빈도수를 세는 프로그램을 짜 봅시다. 

     

    hash로 빈도수를 세면 될것 같은데요..(python이면 collections의 defaultdict를 사용하겠지만..)

    let arr = [
      "hello",
      "world",
      "hello",
      "world",
      "hello",
      "world",
      "show",
      "me",
    ]
    
    func printValues(_ values: [String]) {
      print(values.sorted())
      var result = [String: Int]()
      for e in values {
      	//result[e]가 존재하지 않으면 0, 존재하면 값 가져오는 부분 
        let v = result[e] ?? 0
        result[e] = v + 1
      }
      print(result)
    }
    
    

     

    만약 String이 아니라 다른게 들어오면 제너릭으로 어떻게 구현해야될까요?

     

    객체가 비교 가능해야되니까 "Comparable" protocol은 준수해야될것 같고..

    hash 값을 써야되니까 "Hashable" protocol을 추가적으로 준수해야 될 것 같습니다. 

     

    두개의 Protocol을 준수하려면 어떻게 해야될까요?

    Comparable & Hashable  두개로 연결하면 됩니다. 

     

    // 제약 사항이 여러 개 존재할 경우,
    //  1) <T: Comparable & Hashable>
    //  2) where T: Comparable & Hashable
    
    func printValues<T: Comparable & Hashable>(_ values: [T]) {
      print(values.sorted())  // Comparable
      var result = [T: Int]() // Hashable
      for e in values {
        let v = result[e] ?? 0
        result[e] = v + 1
      }
      print(result)
    }
    
    func printValues<T>(_ values: [T]) where T: Comparable & Hashable
    {
      print(values.sorted()) // Comparable
      var result = [T: Int]() // Hashable
      for e in values {
        let v = result[e] ?? 0
        result[e] = v + 1
      }
    
      print(result)
    }
    
    let arr = [
      "hello",
      "world",
      "hello",
      "world",
      "hello",
      "world",
      "show",
      "me",
    ]
    printValues(arr)

     

    이번에는 사용자가 만든 객체 타입의 빈도수를 세려면 어떻게 해야될까요?

    마찬가지로 "Comparable"과 "Hashable"의 Protocol을 준수하면 됩니다. 

    struct User {
      let name: String // Hashable / Equtable
      let age: Int     // Hashable / Equtable
    }
    
    extension User : Comparable {
      static func < (lhs: User, rhs: User) -> Bool {
        return lhs.name < rhs.name
      }
    }
    
    extension User : Hashable {
        //Equatable
        static func ==(lhs:User, rhs:User) -> Bool {
            return lhs.name == rhs.name && lhs.age == rhs.age
        }
        //Hashable
        func hash(into hasher: inout Hasher) {
            hasher.combine(name)
            hasher.combine(age)
        }
    }
    
    
    let arr2 = [
      User(name: "Tom", age: 42),
      User(name: "Bob", age: 100),
      User(name: "Tom", age: 42),
      User(name: "Bob", age: 100),
      User(name: "Tom", age: 42),
      User(name: "Bob", age: 100),
      User(name: "Tom", age: 42),
      User(name: "Bob", age: 100),
    ]
    printValues(arr2)
    

    Swift의 구조체의 프로퍼티가 Hashable / Equtable에 대한 프로토콜을 만족한다면,  별도의 구현을 제공할 필요가 없습니다

    'Programming > Swift(iOS)' 카테고리의 다른 글

    Swift 화면 전환 방법  (0) 2021.09.07
    mac os에서 시스템 키체인을 사용하고자 합니다.  (0) 2021.06.10
    Swift Generic - 2  (0) 2021.04.06
    Swift Generic - 1  (0) 2021.04.06
    Swift 오류처리 -3  (0) 2021.04.06
Designed by Tistory.