Swift 字符串数组相等字典
Swift Dictionary of string's array equality
我正在尝试创建一个以字符串为键、以字符串数组为值的字典。
然后我想检查这些字典中的 2 个是否相等,如下所示:
let dicOfStringStringAr1: [String : [String]] = ["key1" : ["val", "for key 1"]]
let dicOfStringStringAr2: [String : [String]] = ["key1" : ["val", "for key 1"]]
if dicOfStringStringAr1 == dicOfStringStringAr2 {
print("Dictionary of String Array")
}
但是我得到这个错误:
error: binary operator '==' cannot be applied to two '[String : [String]]' operands
但是如果值是 String 而不是 [String],它就可以工作。
let dicOfStringAr1: [String : String] = ["key1" : "val"]
let dicOfStringAr2: [String : String] = ["key1" : "val"]
if dicOfStringAr1 == dicOfStringAr2 {
print("Dictionary of String Array")
}
我不明白这个问题。
谁能解释一下是什么问题。
查看字典的默认 == Swift 函数后
@warn_unused_result
public func ==<Key : Equatable, Value : Equatable>(lhs: [Key : Value], rhs: [Key : Value]) -> Bool
我意识到没有将值表示为数组的定义,并且 "generic" 值无法解析为集合。 (不知道为什么)。
所以我做了一个 == 函数,它有 [Key : [Value]] 参数。现在代码可以工作了。
@warn_unused_result
public func ==<Key : Equatable, Value : Equatable>(lhs: [Key : [Value]], rhs: [Key : [Value]]) -> Bool {
var result = lhs.count == rhs.count
for (k, v) in lhs {
guard let arValue = rhs[k] where result == true else {
result = false
break
}
result = v == arValue
}
return result
}
有人可以解释为什么在 Swift == 实现中值不能解析为单个项目,是一个数组吗?
幸运的是,您可以通过将字典转换为 NSDictionary 并使用其方法 isEqualToDictionary
来检查这些字典是否相等。例如:
if NSDictionary(dictionary: dicOfStringStringAr1).isEqualToDictionary(dicOfStringStringAr2) {
print("Dictionary of String Array")
}
其实很有道理。从 <Key : Equatable, Value : Equatable>
类型的 ==
函数可以看出,它需要 Value
来符合 Equatable
。默认情况下,Array
类型不符合 Equatable
。 请注意,这并不意味着您不能使用 ==
.
比较两个数组
[1, 2, 3] == ["a", "b", "c"] // false.
符合Equatable
意味着你可以使用==
但不能反之。
您当然可以扩展 Array
类型以符合 Equatable
.
extension Array: Equatable {}
// Implement the following method.
public func ==<T: CollectionType, U: CollectionType>(lhs: T, rhs: U) -> Bool {}
更新
我想说现在不可能为 Array
实施一个合理的 ==
。 (可能在 future swift version)
对于您的具体情况,我认为以下方法足够公平。当您有自定义 struct
时,只需确保它符合 Equatable
.
public func ==<Key : Equatable, Value : CollectionType where Value.Generator.Element: Equatable>(lhs: [Key : Value], rhs: [Key : Value]) -> Bool {
guard lhs.keys.elementsEqual(rhs.keys) else { return false }
for (key, value) in lhs {
if !value.elementsEqual(rhs[key]!) { return false }
}
return true
}
示例为:
struct Number: Equatable {
var x: Int
var y: Int
}
func ==(lhs: Number, rhs: Number) -> Bool {
return lhs.x == rhs.x && lhs.y == rhs.y
}
let dicOfStringStringAr1: [String : [Number]] = ["key1" : [Number(x: 1, y: 2), Number(x: 1, y: 2)]]
let dicOfStringStringAr2: [String : [Number]] = ["key1" : [Number(x: 1, y: 2), Number(x: 1, y: 2)]]
if dicOfStringStringAr1 == dicOfStringStringAr2 {
print("Dictionary of String Array") // "Dictionary of String Array"
}
我正在尝试创建一个以字符串为键、以字符串数组为值的字典。
然后我想检查这些字典中的 2 个是否相等,如下所示:
let dicOfStringStringAr1: [String : [String]] = ["key1" : ["val", "for key 1"]]
let dicOfStringStringAr2: [String : [String]] = ["key1" : ["val", "for key 1"]]
if dicOfStringStringAr1 == dicOfStringStringAr2 {
print("Dictionary of String Array")
}
但是我得到这个错误:
error: binary operator '==' cannot be applied to two '[String : [String]]' operands
但是如果值是 String 而不是 [String],它就可以工作。
let dicOfStringAr1: [String : String] = ["key1" : "val"]
let dicOfStringAr2: [String : String] = ["key1" : "val"]
if dicOfStringAr1 == dicOfStringAr2 {
print("Dictionary of String Array")
}
我不明白这个问题。
谁能解释一下是什么问题。
查看字典的默认 == Swift 函数后
@warn_unused_result
public func ==<Key : Equatable, Value : Equatable>(lhs: [Key : Value], rhs: [Key : Value]) -> Bool
我意识到没有将值表示为数组的定义,并且 "generic" 值无法解析为集合。 (不知道为什么)。
所以我做了一个 == 函数,它有 [Key : [Value]] 参数。现在代码可以工作了。
@warn_unused_result
public func ==<Key : Equatable, Value : Equatable>(lhs: [Key : [Value]], rhs: [Key : [Value]]) -> Bool {
var result = lhs.count == rhs.count
for (k, v) in lhs {
guard let arValue = rhs[k] where result == true else {
result = false
break
}
result = v == arValue
}
return result
}
有人可以解释为什么在 Swift == 实现中值不能解析为单个项目,是一个数组吗?
幸运的是,您可以通过将字典转换为 NSDictionary 并使用其方法 isEqualToDictionary
来检查这些字典是否相等。例如:
if NSDictionary(dictionary: dicOfStringStringAr1).isEqualToDictionary(dicOfStringStringAr2) {
print("Dictionary of String Array")
}
其实很有道理。从 <Key : Equatable, Value : Equatable>
类型的 ==
函数可以看出,它需要 Value
来符合 Equatable
。默认情况下,Array
类型不符合 Equatable
。 请注意,这并不意味着您不能使用 ==
.
[1, 2, 3] == ["a", "b", "c"] // false.
符合Equatable
意味着你可以使用==
但不能反之。
您当然可以扩展 Array
类型以符合 Equatable
.
extension Array: Equatable {}
// Implement the following method.
public func ==<T: CollectionType, U: CollectionType>(lhs: T, rhs: U) -> Bool {}
更新
我想说现在不可能为 Array
实施一个合理的 ==
。 (可能在 future swift version)
对于您的具体情况,我认为以下方法足够公平。当您有自定义 struct
时,只需确保它符合 Equatable
.
public func ==<Key : Equatable, Value : CollectionType where Value.Generator.Element: Equatable>(lhs: [Key : Value], rhs: [Key : Value]) -> Bool {
guard lhs.keys.elementsEqual(rhs.keys) else { return false }
for (key, value) in lhs {
if !value.elementsEqual(rhs[key]!) { return false }
}
return true
}
示例为:
struct Number: Equatable {
var x: Int
var y: Int
}
func ==(lhs: Number, rhs: Number) -> Bool {
return lhs.x == rhs.x && lhs.y == rhs.y
}
let dicOfStringStringAr1: [String : [Number]] = ["key1" : [Number(x: 1, y: 2), Number(x: 1, y: 2)]]
let dicOfStringStringAr2: [String : [Number]] = ["key1" : [Number(x: 1, y: 2), Number(x: 1, y: 2)]]
if dicOfStringStringAr1 == dicOfStringStringAr2 {
print("Dictionary of String Array") // "Dictionary of String Array"
}