Saltar al contenido

¿Cómo comparo dos diccionarios en Swift?

Recabamos por diferentes foros y así darte la respuesta a tu dilema, si continúas con dudas déjanos tu duda y te responderemos porque estamos para ayudarte.

Solución:

Como ya lo mencionó Hot Licks, puede usar el método NSDictionary isEqualToDictionary () para verificar si son iguales de la siguiente manera:

let dic1: [String: AnyObject] = ["key1": 100, "key2": 200]
let dic2: [String: AnyObject] = ["key1": 100, "key2": 200]
let dic3: [String: AnyObject] = ["key1": 100, "key2": 250]

println( NSDictionary(dictionary: dic1).isEqualToDictionary(dic2) )   // true
println( NSDictionary(dictionary: dic1).isEqualToDictionary(dic3) )  // false

también puede implementar un operador personalizado “==” de la siguiente manera:

public func ==(lhs: [String: AnyObject], rhs: [String: AnyObject] ) -> Bool 
    return NSDictionary(dictionary: lhs).isEqualToDictionary(rhs)


println(dic1 == dic2)   // true
println(dic1 == dic3)   // false

Xcode 9 • Swift 4

De los documentos, el diccionario ahora se define como una estructura:

struct Dictionary : Collection, ExpressibleByDictionaryLiteral

Descripción

Una colección cuyos elementos son key-pares de valores. Un diccionario es un tipo de tabla hash que proporciona un acceso rápido a las entradas que contiene. Cada entrada de la tabla se identifica mediante su
key, que es un tipo hash como string o número. Tu usas eso
key para recuperar el valor correspondiente, que puede ser cualquier objeto. En otros lenguajes, los tipos de datos similares se conocen como hashes o matrices asociadas. Cree un nuevo diccionario utilizando un literal de diccionario. Un diccionario literal es una lista separada por comas de keypares de valores, en los que dos puntos separan cada uno key de su valor asociado, rodeado por corchetes. Puede asignar un literal de diccionario a una variable o constante o pasarlo a una función que espera un diccionario.

Así es como crearía un diccionario de códigos de respuesta HTTP y sus mensajes relacionados:

var responseMessages = [200: "OK",
                        403: "Access forbidden",
                        404: "File not found",
                        500: "Internal server error"]

Se infiere que la variable responseMessages tiene tipo [Int: String]. El tipo de clave del diccionario es Inty el tipo de valor del diccionario es String.

Para crear un diccionario sin keypares de valores, use un literal de diccionario vacío ([:]).

var emptyDict: [String: String] = [:]

Cualquier tipo que se ajuste al protocolo Hashable se puede utilizar como tipo de clave de diccionario, incluidos todos los tipos básicos de Swift. Puede utilizar sus propios tipos personalizados como diccionario keys haciéndolos cumplir con el protocolo Hashable.


Ya no necesitamos definir un operador personalizado:

De los documentos:

static func ==(lhs: [Key : Value], rhs: [Key : Value]) -> Bool

Pruebas:

let dic1 = ["key1": 100, "key2": 200]
let dic2 = ["key1": 100, "key2": 200]
let dic3 = ["key1": 100, "key2": 250]

print(dic1 == dic2)   // true
print(dic1 == dic3)   // false

En el ejemplo de arriba todo el diccionario keys y los valores son del mismo tipo. Si intentamos comparar dos diccionarios de tipo [String: Any] Xcode se quejará de que el operador binario == no se puede aplicar a dos [String: Any] operandos.

let dic4: [String: Any] = ["key1": 100, "key2": "200"]
let dic5: [String: Any] = ["key1": 100, "key2": "200"]
let dic6: [String: Any] = ["key1": 100, "key2": Date()]

print(dic4 == dic5)  // Binary operator == cannot be applied to two `[String: Any]` operands

Pero podemos extender el == funcionalidad de operador que implementa un operador infijo, convierte el diccionario Swift en NSDictionary y restringe los valores del diccionario al protocolo Hashable:


Xcode 11 • Swift 5.1

public func ==(lhs: [K: L], rhs: [K: R] ) -> Bool 
   (lhs as NSDictionary).isEqual(to: rhs)


Pruebas:

let dic4: [String: AnyHashable] = ["key1": 100, "key2": "200"]
let dic5: [String: AnyHashable] = ["key1": 100, "key2": "200"]
let dic6: [String: AnyHashable] = ["key1": 100, "key2": Date()]

print(dic4 == dic5)   // true
print(dic4 == dic6)   // false

let dic7: [String: String] = [ "key2": "200"]
let dic8: [String: Date] = [ "key2": Date()]
print(dic7 == dic8)   // false

Actualización de Swift 4:

¡Comparar diccionarios ahora es nativo! (Documentos aquí)


Rápido 3:

Leo Dabus ya tiene una publicación excelentemente escrita con la solución aceptada. Sin embargo, para mí, descubrí que necesitaba un paso más para ser completamente utilizable. Como puede ver en su código, debe configurar el tipo de diccionario en [AnyHashable: Any], o de lo contrario obtendrás Binary operator '==' cannot be applied to two '[String : Any]' operands, para usar un diccionario común para deserializar JSON para mi ejemplo.

Genéricos al rescate !:

// Swift 3.0
func == (left: [K:V], right: [K:V]) -> Bool 
    return NSDictionary(dictionary: left).isEqual(to: right)

o en otro caso tuve, con [String: Any?]:

func == (left: [K:V?], right: [K:V?]) -> Bool 
    guard let left = left as? [K: V], let right = right as? [K: V] else  return false 
    return NSDictionary(dictionary: left).isEqual(to: right)

En Swift 2, cuando ambos Key y Value están Equatable, puedes usar == en el propio diccionario:

public func ==(lhs: [Key : Value], rhs: [Key : Value]) -> Bool

Y, NSObject es Equatable:

public func ==(lhs: NSObject, rhs: NSObject) -> Bool

En su caso, si está trabajando con objetos Obj-C que desea comparar usando isEqual:, simplemente puede usar NSObject como su tipo de valor (en lugar de AnyObject).

Aquí puedes ver las comentarios y valoraciones de los usuarios

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *