Swift词典获得价值的关键

mgi*_*inn 51 dictionary swift

我正在使用类型[UIImage:UIImage]的快速字典,我正在尝试找到给定值的特定键.在Objective-C中我可以使用allKeysForValue,但是对于Swift字典似乎没有这样的方法.我该怎么用?

Mar*_*n R 61

据我所知,没有内置的Swift函数来获取给定值的所有字典键.这是一个可能的实现:

func allKeysForValue<K, V : Equatable>(dict: [K : V], val: V) -> [K] {
    return map(filter(dict) { $1 == val }) { $0.0 }
}
Run Code Online (Sandbox Code Playgroud)

filter降低的所有键值对那些与给定值.的map地图中的(过滤后的)键-值对单独的键.

用法示例:

let dict = ["a" : 1, "b" : 2, "c" : 1, "d" : 2]
let keys = allKeysForValue(dict, 1)
println(keys) // [a, c]
Run Code Online (Sandbox Code Playgroud)

更新Swift 2:从Xcode 7 beta 2开始,现在可以使用类似值的字典的扩展方法来实现(感谢Airspeed Velocity让我在评论中意识到这一点):

extension Dictionary where Value : Equatable {
    func allKeysForValue(val : Value) -> [Key] {
        return self.filter { $1 == val }.map { $0.0 }
    }
}

let dict = ["a" : 1, "b" : 2, "c" : 1, "d" : 2]
let keys = dict.allKeysForValue(1)
print(keys) // [a, c]
Run Code Online (Sandbox Code Playgroud)

Swift 3更新:

extension Dictionary where Value: Equatable {
    func allKeys(forValue val: Value) -> [Key] {
        return self.filter { $1 == val }.map { $0.0 }
    }
}

let dict = ["a" : 1, "b" : 2, "c" : 1, "d" : 2]
let keys = dict.allKeys(forValue: 1)
print(keys) // [a, c]
Run Code Online (Sandbox Code Playgroud)


dfr*_*fri 48

Swift 3:对于双射词典的特殊情况,它是一种更高效的方法

如果反向字典查找用例涵盖了在键和值之间具有一对一关系的双射字典,则收集 - 穷举filter操作的替代方法是使用更快的短路方法来找到一些密钥(如果存在的话).

extension Dictionary where Value: Equatable {
    func someKey(forValue val: Value) -> Key? {
        return first(where: { $1 == val })?.key
    }
}
Run Code Online (Sandbox Code Playgroud)

用法示例:

let dict: [Int: String] = [1: "one", 2: "two", 4: "four"]

if let key = dict.someKey(forValue: "two") { 
    print(key)
} // 2
Run Code Online (Sandbox Code Playgroud)


vac*_*ama 41

你可以使用allKeys(for:)如果你施放到NSDictionary:

let keys = (dict as NSDictionary).allKeys(for: image) as! [UIImage]
Run Code Online (Sandbox Code Playgroud)


bso*_*sod 29

了解这些答案中的大多数在搜索之前都会获得字典的整个键集。此答案使用first(where:)找到密钥后返回的方法。

Swift 5(内联)

let someValue = UIImage()

if let key = someDictionary.first(where: { $0.value == someValue })?.key {
    print(key)
}
Run Code Online (Sandbox Code Playgroud)

斯威夫特 5(扩展)

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

print(someDictionary.key(from: someValue)) // optional

if let key = someDictionary.key(from: someValue) {
    print(key) // non-optional
}
Run Code Online (Sandbox Code Playgroud)

  • 棒极了!这应该是当前的正确答案。 (4认同)

小智 8

这是我在博客上写的另一种方法.它是针对Swift 2.2进行测试的.

extension Dictionary where Value: Equatable {
  /// Returns all keys mapped to the specified value.
  /// ```
  /// let dict = ["A": 1, "B": 2, "C": 3]
  /// let keys = dict.keysForValue(2)
  /// assert(keys == ["B"])
  /// assert(dict["B"] == 2)
  /// ```
  func keysForValue(value: Value) -> [Key] {
    return flatMap { (key: Key, val: Value) -> Key? in
      value == val ? key : nil
    }
  } 
}
Run Code Online (Sandbox Code Playgroud)

它是发布到此线程的最有效的实现,它产生映射到指定值的所有键,因为它使用flatMap而不是filter然后使用map.如果你感兴趣的话flatMap,我在Swift文章的高阶函数中写过.

另外,因为我的方法是通用的(凭借在为Dictionary<Key,Value>通用类),你不需要它的结果转换键的类型,使用时需要allKeysForObject(_:)NSDictionary.


Lea*_*ner 8

let dict = ["key1":2,"key2":6,"key3":8,"key4":8]
let searchingValue = 8
let b = dict.filter {$0.value == searchingValue}
let a = b.keys.first
Run Code Online (Sandbox Code Playgroud)

b提供的地图searchingValue["key4":8,"key3":8]

b.keys.first 提供所有已过滤键的第一个元素,即 g

a 是价值的关键 8


Teo*_*ori 6

Swift 2版本:

func allKeysForValue<K, V : Equatable>(dict: [K : V], val: V) -> [K] {
    return dict.filter{ $0.1 == val }.map{ $0.0 }
}
Run Code Online (Sandbox Code Playgroud)


cou*_*elk 6

如果你需要为某个值找到一些键(例如,如果有多个键,而不是任何一个键,则不是全部键):

extension Dictionary where Value: Equatable {

    func someKeyFor(value: Value) -> Key? {

        guard let index = indexOf({ $0.1 == value }) else {
            return nil
        }

        return self[index].0

    }

}
Run Code Online (Sandbox Code Playgroud)

nil如果没有值的这样的键,则返回上面的值.