【问题标题】:How to use multiple key for the same value in an Swift Dictionary?如何在 Swift Dictionary 中为相同的值使用多个键?
【发布时间】:2018-04-02 10:58:32
【问题描述】:

如何将用户记录存储到 Swift Dictionary,但通过两种类型的键索引它们:userIDfirstName?有可能吗?

如果删除了一个值,则表达式users[aUserID]user[aFirstName] 都应该返回nil

【问题讨论】:

    标签: ios swift dictionary


    【解决方案1】:

    字典不关心唯一值,它们只关心唯一键。因此,您可以在字典中拥有任意多个相同的值,只要它们的键都不同。

    解决您的问题的方法是隐藏所有必要的逻辑,以使字典键在包装器类中保持同步:

    struct User {
        let userId: Int
        let firstName: String
        // more user properties
    }
    
    class UserDict {
    
        private var dict = [String: User]()
    
        subscript(key: String) -> User? {
            return dict[key]
        }
    
        subscript(key: Int) -> User? {
            return dict["\(key)"]
        }
    
        func add(_ user: User) {
            dict[user.firstName] = user
            dict["\(user.userId)"] = user
        }
    
        func remove(forKey key: String) {
            if let user = dict[key] {
                dict.removeValue(forKey: user.firstName)
                dict.removeValue(forKey: "\(user.userId)")
            }
        }
    
        func remove(forKey key: Int) {
            remove(forKey: "\(key)")
        }
    
        var count: Int {
            return dict.count / 2
        }
    }
    

    【讨论】:

      【解决方案2】:

      可以为同一个值设置多个键,请考虑以下示例:

      class Value {
          var name = "John"
      }
      
      var dictionary: [String: Value] = [:]
      
      var value1 = Value()
      
      dictionary["key1"] = value1
      dictionary["key2"] = value1
      
      value1.name = "Theresa"
      
      dictionary["key1"]?.name // "Theresa"
      dictionary["key2"]?.name // "Theresa"
      

      关于你问题的第二部分:

      如果删除值,则表达式 users[aUserID] 和 user[aFirstName] 都应返回 nil。

      当您这样做 dict["key1"] = nil 时,key2 的值仍然存在并且将是 value1,因此您可以创建一个自定义 subscript,通过在 @ 中找到相同的 values 来处理该问题987654328@.

      【讨论】:

      • 对于第二部分,IMO,在你的类中用 .weakMemory 值指针选项包装 NSMapTable 会更容易。
      • @user28434 请记住,NSMapTable 是一个通用的 Objective-C 类。 OP 要求在问题上带有 swift 标签的 swift Dictionary。使用它也会将您限制为仅限 NSObject 类型。此外,要以这种方式使用NSMapTable,您最终还是会使用自定义subscript 对其进行扩展。
      • 这就是为什么我要包装它。就像在 Swift 课程中一样。取 ObjC 类型 NSMapTable 并将其包装为 Swift 类型。而且,ofc,它需要定义自己的subscript
      • 另外,从 Swift 3.0 开始,对 NSObject 子类的限制是无关紧要的,因为现在任何类型都可以在底层封装到 SwiftValue 中,ObjC 代码将其视为 NSObject 子类。
      猜你喜欢
      • 2022-11-10
      • 2017-04-29
      • 2015-09-13
      • 1970-01-01
      • 1970-01-01
      • 2014-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多