Saltar al contenido principal

Comparar objetos en Flutter con el paquete equatable

· 4 min de lectura
Yayo Arellano
Software Engineer
Youtube video player

Youtube video player

En este artículo, vamos a ver cómo funciona la igualdad en Flutter y Dart y como el paquete Equatable nos ayuda a tener un código más limpio sin necesidad de escribir tanto código repetitivo.

Ya sabemos que si queremos comparar dos variables podemos usar el operador ==. Por ejemplo, si queremos comparar dos cadenas de texto, el código es:

  final car1 = "Toyota";
final car2 = "Toyota";
print(car1 == car2); // Resultado: true

Y si queremos comparar dos números, el código es:

  final phone1 = 52123456;
final phone2 = 52123456;
print(phone1 == phone2); // Resultado: true

Veamos el resultado del código anterior en DartPad:

Comparar dos objetos de la misma clase

En los ejemplos anteriores vimos que es muy sencillo comparar dos variables usando == pero cuando queremos comparar dos objetos de la misma clase ya no es tan sencillo.

Sí tenemos la siguiente clase:

class Car {
final String brand;

Car(this.brand);
}

Y creamos dos objetos:

  final car1 = Car('Toyota');
final car2 = Car('Toyota');
print(car1 == car2); // false

A simple vista podemos decir que car1 y car2 son iguales, pero no es cierto. El resultado de comparar car1 y car2 es false

Corramos el código anterior en DartPad:

¿Por qué pasa esto si todos sus valores son iguales? La respuesta es simple, en Dart por defecto el operador == verifica la posición en memoria y no las propiedades de cada objeto. Y ya que car1 y car2 están en posiciones de memoria diferente, el resultado de la comparación es false.

Usando el constructor const

Utilizar el constructor const le dice a Dart que solo debe crear una instancia de una clase para un conjunto de valores dados en tiempo de compilación. Corramos el código anterior en DartPad pero esta vez utilizando constructores const:

Podemos ver que usar el constructor const resuelve el problema al comparar dos objetos, pero, esto solo funciona para objetos de los cuales conocemos su valor en tiempo de compilación. No hay forma de utilizar el constructor const en objetos creados en tiempo de ejecución. Es aquí donde entra el paquete Equatable

El paquete Equatable

Sin utilizar el paquete Equatable para comparar las propiedades de dos objetos y ver si son iguales tenemos que sobreescribir == y hashCode. El código de la clase Car será:

class Car {
final String brand;

const Car(this.brand);


bool operator ==(Object other) =>
identical(this, other) ||
other is Car &&
runtimeType == other.runtimeType &&
brand == other.brand;


int get hashCode => brand.hashCode;
}

Equatable es un paquete que simplifica el proceso de comparar dos objetos de la misma clase sin sobreescribir == y hashCode.

Internamente, Equatable sobreescribe == y hashCode para que nosotros no tengamos que perder tiempo escribiendo código repetitivo.

Utilizando Equatable el código anterior será:

import 'package:equatable/equatable.dart';

class Car extends Equatable {
const Car(this.brand);

final String brand;


List<Object> get props => [brand];
}

Y si agregamos más propiedades como name el código será:

class Car extends Equatable {
const Car(this.brand, this.name);

final String brand;
final String name;


List<Object> get props => [brand, name];
}

Corramos el código en DartPad para ver el resultado:

Podemos ver que el resultado es true cuando los valores de las propiedades son los mismos. Intenta cambiando los valores de car2 ¿Cuál es el resultado?

Conclusión

El paquete Equatable es muy importante si queremos comparar dos objetos por el valor de sus propiedades, sin ßél tendríamos que escribir mucho código repetitivo.