11.02.2008

Buscando un Objeto en una Lista Genérica Utilizando el Método Contains

Una de las tareas más comúnes cuando estamos desarrollando una aplicación que utiliza una lista de tipo Generic, es el identificar si en la lista existe un objeto determinado. Para llevar a cabo esta labor, existe un método en la clase List<T> llamado Contains que hace precisamente esto. Este método determina si los objetos son iguales utilizando el comparador de igualdad EqualityComparer.Default para el tipo T, el tipo de los elementos en la lista. Este método lleva a cabo una búsqueda lineal, por lo que esta es una operación O(n), donde n = todal de elementos en la lista.

Este comparador determina a través de su propiedad Default si el tipo T implementa la interface genérica System.IEquatable; si es así, retorna un EqualityComparer que utiliza esa implementación. Si no lo implementa, retorna el EqualityComparer que utiliza Object.Equals y Object.GetHasCode de T. En otras palabras, si tenemos implementado un método para comparar dentro de nuestra clase T, se utiliza este método, de lo contrario, se utiliza el método por defecto Object.Equals. El siguiente ejemplo muestra como se implementa este método, y como se busca un objeto en una lista genérica utilizando el método Contains.

Primeramente, vamos a utilizar la clase persona utilizada en ejemplos anteriores, pero en esta oportunidad le vamos a agregar la implementación de IEquatable.

public class Persona : IEquatable<Persona>
{
private int m_Id;
private string m_Nombre;
private string m_Apellido1;
private string m_Apellido2;
private string m_Pais;


Seguidamente vamos a implementar el método Equals de la interfase IEquatable. En este método debemos definir como vamos a llevar a cabo la comparación entre la instancia actual, y la que viene por parámetro. En nuestro ejemplo, vamos a decir que un objeto es igual a otro si el nombre de la persona de ambos objetos es el mismo, y si el Id de los objetos es el mismo. La implementación de este método es la siguiente:



#region IEquatable<Persona> Members

public bool Equals( Persona other )
{
if (this.Nombre == other.Nombre
&& this.Id == other.Id)
return true;
return false;
}

#endregion



Para probar nuestro método de comparación, vamos a crear una lista genérica con 6 personas, tal y como lo hicimos en los ejemplos anteriores.



List<Persona> listaPersonas = new List<Persona>( );
Persona p1 = new Persona(1, "Manuel", "Perez", "Ruiz", "Mexico");
Persona p2 = new Persona(2, "Arnoldo", "Rojas", "Gomez", "Panama");
Persona p3 = new Persona(3, "Juan", "Ramos", "De la O", "España");
Persona p4 = new Persona(4, "Miguel", "Cortez", "Valerio", "Costa Rica");
Persona p5 = new Persona(5, "Andres", "Perez", "Fonseca", "Mexico");
Persona p6 = new Persona(6, "Antonio", "Aleman", "Rodriguez", "Mexico");
listaPersonas.Add(p1);
listaPersonas.Add(p2);
listaPersonas.Add(p3);
listaPersonas.Add(p4);
listaPersonas.Add(p5);
listaPersonas.Add(p6);



Por último, vamos a crear una instancia de persona y la vamos a incializar con los datos de la persona p2, y vamos a buscar en la lista si esta nueva instancia que llamaremos personaABuscar contiene los datos de una persona que si existe dentro de la lista que acabamos de crear - listaPersonas. Esta búsqueda la haremos utilizando el método Contains, el cual como mencionamos anteriormente, utiliza el método Equals implementado en la clase Persona.



Persona personaABuscar = new Persona(2, "Arnoldo", "Rojas", "Gomez", "Panama");
if (listaPersonas.Contains(personaABuscar))
Console.WriteLine("{0} {1} existe en la lista",
personaABuscar.Nombre, personaABuscar.Apellido1);
else
Console.WriteLine("{0} {1} existe NO en la lista",
personaABuscar.Nombre, personaABuscar.Apellido1);



El resultado al ejecutar el código anterior – este proyecto al igual que los anteriores es un proyecto de consola – se ve en la siguiente imagen.



image

2 comentarios:

Gear.KR4 dijo...

Gracias, me ha servido mucho, busque varias formas, implemente los operadores = y <> pero no funciono, tampoco sobrecargando la funcion equal que se hereda de object, pero si tras implementar la interfaz funciona perfecto.

Atte. Gear.KR4

DarkLancelot dijo...

Buen post, me ayudo bastante la info ñ.ñ