【问题标题】:Reverse Swift dictionary lookup反向 Swift 字典查找
【发布时间】:2016-12-29 16:53:13
【问题描述】:

我有一本像这样的字典:

let ints: [Int: String] = [
    0: "0",
    1: "1",
    2: "2",
    3: "3",
    4: "4",
    5: "5",
    6: "6",
    7: "7",
    8: "8",
    9: "9",
    10: "A",
    11: "B",
    // etc...
]

我可以用ints[5] 查找一个整数来得到"5"。如何从字符串中查找整数?我想做类似ints.keys["5"] -> 5

目前,我刚刚把字典倒过来写了:

let chars: [String: Int] = [
    "0": 0,
    "1": 1,
    "2": 2,
    "3": 3,
    "4": 4,
    "5": 5,
    "6": 6,
    "7": 7,
    "8": 8,
    "9": 9,
    "A": 10,
    "B": 11,
    // etc...
]

我可以通过chars["5"] 获取5,但这是一个麻烦的解决方案,因为我的字典很大,并且希望能够在需要时轻松更改它。

澄清

我不想以编程方式构建字典,而只是保留一个硬编码。

【问题讨论】:

  • 有什么理由用手把它们写下来吗?映射看起来很基本。
  • 为了让问题更容易解释,我把它写下来了。
  • 好吧,你说得太简单了。映射甚至是可逆的吗?总是1:1吗?
  • Swift dictionary get key for value 的可能重复项。 – 但是,如果您对 same 字典进行 许多 查找,那么我建议您使用一次反向映射创建一个字典。

标签: arrays swift dictionary


【解决方案1】:

您可以利用 Swift 字典实现 Collection 协议这一事实,该协议扩展了 Sequence 协议,并使用 first 方法返回与给定条件匹配的序列的第一个元素:

extension Dictionary where Value: Equatable {
    func key(forValue value: Value) -> Key? {
        return first { $0.1 == value }?.0
    }
}

ints.key(forValue: "5")    // 5
ints.key(forValue: "99")   // nil

上面的代码作为Dictionary 可以被同化为(Key, Value) 对的序列。唯一需要注意的是,如果多个键与相同的值匹配,我们只会得到其中一个键,并且说哪个键并不确定——尽管如果你的字典有一对一映射,你就没有这个问题。

【讨论】:

    【解决方案2】:

    我使用 Martin R 的链接找到了这个解决方案:

    let int = 11
    print(chars.filter{$1 == int}.map{$0.0}[0]) // B
    

    【讨论】:

    • 如果您知道字典中键映射的值 (chars) 是双射的(一对一),您可以使用 first 而不是 filter:前者将允许第一次命中时提前退出(短路),而filter 将通过完整的无序字典。例如,print(chars.first(where: { $1 == int })?.0 ?? "No such value").
    • 是的,它是双射的。谢谢你,它加快了速度。
    【解决方案3】:

    另一种方法是以编程方式构建 1:1 反向查找:

        var chars = ["a":1,"b":2,"c":3]
    
        var ints = [Int:String]()
        for pair in chars { ints[pair.value] = pair.key }
    

    ints 包含:

        [1:"a", 2:"b", 3:"c"]
    

    如果你多次使用它会很有效率。

    【讨论】:

      【解决方案4】:

      就像@dfri 提到的,您可以使用first 方法来获取给定值的第一个键:

      extension Dictionary where Value: Equatable {
      
          func key(for value: Value) -> Key? {
              return first(where: { $1 == value })?.key
          }
      
      
      }
      

      【讨论】:

      • 我已经将我的解决方案添加到dupe target,虽然... :) 另请注意,这本身并没有获得“第一个”键,因为字典是无序的集合(所以“第一”,在语义上,在这里没有任何意义)。但是,它确实获得了 some 键,这可能是具有所提供值的单个键,或者只是我们在无序集合中第一次偶然发现的许多键中的一些。
      猜你喜欢
      • 2021-01-21
      • 2011-08-30
      • 2021-12-22
      • 2010-09-06
      • 2018-06-04
      • 2011-02-16
      • 2018-03-30
      • 1970-01-01
      • 2011-10-01
      相关资源
      最近更新 更多