【问题标题】:Overriding default behaviour of dictionaries in Swift to ignore zero values?覆盖 Swift 中字典的默认行为以忽略零值?
【发布时间】:2015-03-10 15:01:21
【问题描述】:

我想创建一种数据类型,其行为类似于字典,但忽略任何值为 0 的键,例如考虑一个假设的例子:

typealias SpecialDict = Dictionary<String,Int>
let testA: SpecialDict = ["a":1, "b":4, "c":0]
let testB: SpecialDict = ["a":1, "b":4]
testA == testB // should evaluate as true

我不确定是否会更好:

  • 覆盖 == 以提供此行为,每次比较两个字典时都要付出代价
  • 覆盖 updateValue(_:forKey:) 以便每当我们尝试将值设置为 0 时,它只会从字典中删除相应的键(首选)
  • 完全尝试不同的数据类型

另外,创建具有固定键列表的字典的方法(即您不能添加或删除键,只需更改它们的值)也可以。

【问题讨论】:

  • 它可能对您的用例没有帮助,但您可以利用将nil 分配给字典值会删除它的事实:var d = ["a":1,"b":2,"c":3];d["c"]=nil;println(d) // no "c" entry

标签: swift dictionary overriding


【解决方案1】:

我想说最简单的方法是创建自己的struct,它的行为方式如你所愿。我会这样做:

struct MyDict {

    private var dictionary = [String: Int]()

    subscript(key: String) -> Int? {
        get {
            return dictionary[key]
        }
        set {
            if newValue! != 0 {
                dictionary[key] = newValue
            } else {
                dictionary.removeValueForKey(key)
            }
        }
    }
}

但请记住,此结构不是字典,因此您必须实现所需的每个功能。

【讨论】:

  • @Matthew 我根据它更新了我的答案。据我所知,你不能覆盖全局函数(比如==),因为结果会模棱两可,而且字典是一个结构,所以它不能是一个超类来覆盖它的一个方法,这就是我建议这种方法的原因.
  • @Matthew 您在此处所做的操作已被 == 覆盖,适用于所有 string-to-int 字典,而不仅仅是特殊字典。 typealias 听起来就是这样——一个别名,而不是不同的类型。
  • 确实如此,但使用该实现您不会覆盖任何内容,因为字典的 == 签名如下所示: func ==(lhs: DictionaryIndex, rhs: DictionaryIndex) -> Bool(你可以在这里看到:swiftdoc.org/operator/eqeq),所以基本上你只是创建了一个新函数,但没有覆盖任何东西。
  • @DánielNagy 严格来说,他已经覆盖了==,只是比现有字典== 具有更高的优先级,因为StringK: Equatable 更专业
  • @Dániel 重载,而不是覆盖,我猜,但这些是相当松散的术语......阴影表明旧版本现在无法访问,但它仍然存在匹配它但不是[String:Int]-特定版本。
猜你喜欢
  • 1970-01-01
  • 2019-08-17
  • 1970-01-01
  • 2011-12-20
  • 1970-01-01
  • 1970-01-01
  • 2013-03-10
  • 2023-03-21
相关资源
最近更新 更多