Introducción
Sucede muchas veces que tenemos una lista con diversos ítems y es necesario saber cuales se repiten en base a un criterio especifico.
Si s esta desarrollando una aplicación con .net 3.5 o superior, lo primero que viene a la mente es utilizar linq, pero que sucede si se desarrolla sin esta tecnología, como resolver el problema.
Es por ello que este articulo propondrá un caso practico en donde se intentara brindar una solución.
El problema
Se dispone de una lista de archivos en una variable del tipo List<string>, y de esta se quiere saber cuantos ítems con distinta extensión se encuentran cargados.
Usando Linq
Esta primera solución seria la clásica, si uno dispone de Linq, como se observara es muy simple.
[C#]
static void Main(string[] args) { List<string> lista = new List<string>() { "produtos.txt", "reporte.doc", "listado.txt", "ventas.xls", "servicios.doc", "detalles.txt" }; var query = from item in lista let extension = item.Split('.')[1] group item by extension into g select new { Key = g.Key, Values = g }; foreach (var item in query) { Console.WriteLine(string.Format("{0} - {1}", item.Key, item.Values.Count())); } Console.ReadLine(); }
[VB.NET]
Friend Shared Sub Main(ByVal args As String()) Dim lista As New List(Of String)() lista.Add("produtos.txt") lista.Add("reporte.doc") lista.Add("listado.txt") lista.Add("ventas.xls") lista.Add("servicios.doc") lista.Add("detalles.txt") Dim query = From item In lista _ Let extension = item.Split("."c)(1) _ Group item By Key = extension Into Group _ Select Key, Values = Group For Each item In query Console.WriteLine(String.Format("{0} - {1}", item.Key, item.Values.Count())) Next Console.ReadLine() End Sub
Usando Dictionary<>
La alternativa sin Linq, involucra el uso de diccionarios genéricos, al cual mediante un proceso secuencial será cargado con la información agrupada.
[C#]
static void Main(string[] args) { List<string> lista = new List<string>() { "produtos.txt", "reporte.doc", "listado.txt", "ventas.xls", "servicios.doc", "detalles.txt" }; Dictionary<string, int> contador = new Dictionary<string, int>(); foreach(string item in lista) { string extension = item.Split('.')[1]; if (contador.ContainsKey(extension)) contador[extension]++; else contador.Add(extension, 1); } // // se muestra el resultado en pantalla // foreach (KeyValuePair<string, int> item in contador) { Console.WriteLine(string.Format("{0} - {1}", item.Key, item.Value)); } Console.ReadLine(); }
[VB.NET]
Friend Shared Sub Main(ByVal args As String()) Dim lista As New List(Of String)() lista.Add("produtos.txt") lista.Add("reporte.doc") lista.Add("listado.txt") lista.Add("ventas.xls") lista.Add("servicios.doc") lista.Add("detalles.txt") Dim contador As New Dictionary(Of String, Integer)() For Each item As String In lista Dim extension As String = item.Split("."c)(1) If contador.ContainsKey(extension) Then contador(extension) += 1 Else contador.Add(extension, 1) End If Next ' ' se muestra el resultado en pantalla ' For Each item As KeyValuePair(Of String, Integer) In contador Console.WriteLine(String.Format("{0} - {1}", item.Key, item.Value)) Next Console.ReadLine() End Sub
En el ejemplo se se recorre la lista preguntando si la extensión ya ha sido registrada, para esto se hace uso del método ContainsKey() que proporciona el diccionario.
Si el ítem se encuentra se incremente en uno, sino se agrega por primera vez a la colección.
Al final se recorre los acumulado y se despliega en pantalla.
Genial, contesta a una pregunta que dejé en los foros de msdn. Gracias!
ResponderEliminarhola Leandro, primero que nada quiero decirte que sos muy bueno ya que muchas de las dudas que tengo desde que comence con .net las evacuo con tus explicaciones. queria preguntarte si existe la posibilidad de buscar un objeto en una lista de objetos. por ejemplo:
ResponderEliminarlist gente = new list<personas<();
gente.add("juan",23,"masculino");
gente.add("pepe",53,"masculino");
gente.add("ana",33,"femenino");
mas abajo en el codigo quiero agregar otra persona y es :
persona nueva = new persona();
persona.nombre = "ana";
persona.edad = "33";
persona.sexo = "femenino";
y ahora es donde quiero hacer lo siguiente :
if(gente.contains(persona) == false)
{ gente.add(persona)}
esta bien esto??
Desde ya gracias por tu ayuda.
hola
EliminarPodrias buscarlo usando linq
bool existe = gente.Any(x=> x.nombre == "ana");
if(existe){ ...
Ahora bien si lo que quieres es compara una entidad completa vas a tener que implementar alguna interfaz como ser IEquatable<>
Change how List.Contains() works
entonces si vas a poder usar el Contains() ya que la instance define el metodo donde indicas como se compara la entidad con otra
saludos
Hola Leandro, necesito el codigo para poder recorrer dos listas con valores y en una tercera lista mostrar la suma de cada valor de cada lista.
ResponderEliminarosea: lista 1 y lista 2 contiene tarea,duracion y en la otra lista mostar tarea y resultado.
soy novato y quiero aprender gracias
o tambien si cargo cada lista a un datagridview en wpf y recorrer cada datagrid y colocar la suma de esas celdas en una celda. gracias
ResponderEliminarcomo funcionaria esto con los numeros, digamos que yo quiero saber cual es el numero que mas se repite
ResponderEliminarPor cierto muy buen aporte
Hola, te hago una consulta, estoy trabajando una solicion en Visual Basic .net desarrollada en capas, hasta ahora la conectaba por ODBC a Informix, pero debo vambiarla a MySql, quizá tengas algúna forma de conectarla ya en el blog y no la encontré.
ResponderEliminarMuchas gracias.