Swift字典获取价值的关键
我正在使用types[UIImage:UIImage]的快速字典,我试图find一个给定值的特定键。 在Objective-C中,我可以使用allKeysForValue,但似乎没有这样的Swift字典的方法。 我应该使用什么?
你可以使用allKeys(for:)
如果你转换成NSDictionary
:
let keys = (dict as NSDictionary).allKeys(for: image) as! [UIImage]
据我所知,没有内置的Swift函数来获取给定值的所有字典键。 这是一个可能的实现:
func allKeysForValue<K, V : Equatable>(dict: [K : V], val: V) -> [K] { return map(filter(dict) { $1 == val }) { $0.0 } }
filter
将所有键值对都缩小为具有给定值的键值对。 map
将(过滤的)键值对单独映射到键。
用法示例:
let dict = ["a" : 1, "b" : 2, "c" : 1, "d" : 2] let keys = allKeysForValue(dict, 1) println(keys) // [a, c]
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]
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]
Swift 3:针对双射字典的特例更为高效的方法
如果反向字典查找用例覆盖了键和值之间具有一对一关系的双射字典,则对收集 – 穷举filter
操作的替代方法将使用更快的短路方法来查找某个键(如果存在)。
extension Dictionary where Value: Equatable { func someKey(forValue val: Value) -> Key? { return first(where: { $1 == val })?.key } }
用法示例:
let dict: [Int: String] = [1: "one", 2: "two", 4: "four"] if let key = dict.someKey(forValue: "two") { print(key) } // 2
这是我在博客上写的另一种方法。 它是针对Swift 2.2进行testing的。
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 } } }
这是发布到这个线程的最有效的实现,它产生所有映射到指定值的键,因为它使用flatMap
,而不是filter
和map
。 如果你有兴趣的话,我在Swift文章的高级函数中写了关于flatMap
内容。
另外,因为我的方法是通用的(通过在Dictionary<Key,Value>
generics类中),所以不需要将其结果转换为键types,这在使用NSDictionary
allKeysForObject(_:)
时是必需的。
Swift 2版本:
func allKeysForValue<K, V : Equatable>(dict: [K : V], val: V) -> [K] { return dict.filter{ $0.1 == val }.map{ $0.0 } }
如果你需要find一个关键的值(即不是所有的人,如果有不止一个,而只是任意一个):
extension Dictionary where Value: Equatable { func someKeyFor(value: Value) -> Key? { guard let index = indexOf({ $0.1 == value }) else { return nil } return self[index].0 } }
如果没有这个值的话,上面返回nil
。