我正在使用类型为[UIImage:UIImage]的Swift字典,并尝试查找给定值的特定键。在Objective-C中,我可以使用allKeysForValue,但在Swift字典中似乎没有这样的方法。我应该使用什么?
我使用的是一个类型为 [UIImage:UIImage] 的 Swift 字典,我想要根据给定的值找到对应的键。在 Objective-C 中,我可以使用 allKeysForValue 方法,但是在 Swift 字典中似乎没有这个方法。请问我该使用什么方法呢?我正在使用类型为[UIImage:UIImage]的Swift字典,并尝试查找给定值的特定键。在Objective-C中,我可以使用allKeysForValue,但在Swift字典中似乎没有这样的方法。我应该使用什么?
我使用的是一个类型为 [UIImage:UIImage] 的 Swift 字典,我想要根据给定的值找到对应的键。在 Objective-C 中,我可以使用 allKeysForValue 方法,但是在 Swift 字典中似乎没有这个方法。请问我该使用什么方法呢?如果反向字典查找用例涵盖具有键和值之间一对一关系的双射字典,则与集合穷举的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
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]
请注意,大多数答案在搜索之前会获取字典的全部键集。此答案使用first(where:)
方法,在找到键后返回。
Swift 5(内联)
if let key = someDictionary.first(where: { $0.value == someValue })?.key {
// use key
}
Swift 5 (扩展)
extension Dictionary where Value: Equatable {
func key(from value: Value) -> Key? {
return self.first(where: { $0.value == value })?.key
}
}
使用方法
let key = someDictionary.key(from: someValue)) // optional
if let key = someDictionary.key(from: someValue) {
// non-optional
}
allKeys(for:)
,如果你将其转换为 NSDictionary
:let keys = (dict as NSDictionary).allKeys(for: image) as! [UIImage]
let keys = (ItemDict as NSDictionary).allKeysForObject(orderItems[indexPath.row])
然后你可以像这样访问:let someIntValue = keys[0].integerValue;
非常好用,谢谢! - c0d3p03tlet keys =(dict as NSDictionary).allKeys(for:image)as![UIImage]
- BitParserlet dict = ["key1":2,"key2":6,"key3":8,"key4":8]
let searchingValue = 8
let b = dict.filter {$0.value == searchingValue}
let a = b.keys.first
b
提供具有 searchingValue
的映射,其中 ["key4":8,"key3":8]
b.keys.first
提供所有筛选后键的第一个元素,即 g
a
是值为 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
}
}
}
flatMap
而不是filter
和map
。如果您感兴趣,我在我的Swift高阶函数文章中讲解了flatMap
。此外,因为我的方法是通用的(由于位于Dictionary<Key,Value>
通用类中),所以您不需要将其结果转换为键的类型,这在使用NSDictionary
的allKeysForObject(_:)
时是必要的。Swift 2 版本:
func allKeysForValue<K, V : Equatable>(dict: [K : V], val: V) -> [K] {
return dict.filter{ $0.1 == val }.map{ $0.0 }
}
$0.1
和 $0.0
而不是 $0
和 $1
呢? - JW.ZGkey
和value
才是字典元素,对吧?因为dictionary = [key:valule]
。 - JW.ZG$0
是字典中的第一个元素吗?就像 [firstKey:firstValue]
这样吗? - JW.ZGextension Dictionary where Value: Equatable {
func someKeyFor(value: Value) -> Key? {
guard let index = indexOf({ $0.1 == value }) else {
return nil
}
return self[index].0
}
}
nil
将被返回。如果您需要为特定值获取任何键,则此方法适用。在我的情况下,这是最简单的方法。希望它能帮到您:
extension Dictionary where Key == String, Value: Equatable {
func key(for value: Value) -> Key? {
return compactMap { value == $1 ? $0 : nil }.first
}
}
someValue
代表你要查找的假设值。dictionary.filter{$0.value == someValue}.keys