Neste artigo vou apresentar algumas fomas de encontrar itens duplicados em uma lista. |
Hoje nosso objetivo será retornar ou contar o número de ocorrências de um objeto
contido em uma lista List<T>que atenda a um critério de busca.
Vamos usar as seguintes abordagens:
Criar métodos de extensão para a Lista
Criar o método de extensão GetTodos() que retorna todos os objetos que atendam ao critério de busca em uma lista ordenada ou não ordenada;
Criar o método de extensão BinarySearchGetTodos() que retorna todos os objetos que atendem o critério em uma lista ordenada;
Criar o método ContaTodos() que conta o número de vezes que um item aparece na lista ordenada ou não;
Criar o método
BinarySearchContaTodos() que conta o número
de vezes que um item aparece na lista ordenada;
Usar LINQ
Usar o método GroupBy()
Usar o Set
Vamos iniciar ...
Criando métodos de extensão para a lista
Vamos criar um projeto Console para .NET Core usando o VS
2022 no ambiente do .NET 8.
Vamos criar uma classe chamada CollectionExtensionMethods onde vamos implementar 4 métodos de extensão
static class CollectionExtensionMethods { // retorna todos objetos que atendemo critério // em uma lista List<T> ordenada ou não ordenada public static IEnumerable<T> GetTodos<T>(this List<T> minhaLista, T valor) => minhaLista.Where(t => t.Equals(valor));
// Retorna todos os objetos que atendem o critério na lista ordenada // procura pelo primeiro item // Conta o número de vezes que um item aparece // Conta o número de vezes que um item aparece na lista ordenada } |
A principal diferença entre os métodos GetTodos() e BinarySearchGetTodos() e se a busca será feita em uma lista ordenada ou não ordenada.
Os métodos BinarySearchGetTodos() e
BinarySearchContaTodos() usam o método BinarySearch
que usa
um algoritmo de pesquisa binária para localizar um elemento específico em
uma List<T>classificado ou parte dele.
A busca/pesquisa binária é um algoritmo que implementa o paradigma Divisão e Conquista para encontrar um elemento em uma lista ordenada. Uma analogia ao funcionamento desse algoritmo seria a busca de uma palavra em dicionário.
Vamos fazer um teste usando o método GetTodos() em uma lista usando o código abaixo:
using ProcuraItensDuplicados.Extensions;
List<int> listaRetorno = new List<int>() { -1,
-1, 1, 2, 2, 2, 2, 3, 100, 78, 14, 2, 4, 5 };
do IEnumerable<int> items = listaRetorno.GetTodos(numero);
if (items.Count() > 0) |
Criamos uma lista de inteiros e a seguir podemos informar um número e verificar se ele existe na lista e se esta duplicado.
Executando o projeto podemos ter o seguinte resultado:
Obtemos como resultado um IEnumerable contendo os números duplicados.
Usando o método GroupBy da LINQ
Nesta abordagem a idéia é usar o método Enumerable.GroupBy() para agrupar os elementos com base em seu valor, filtrar os grupos que aparecem mais de uma vez e recuperar as chaves duplicadas.
Veja como ficaria o código:
Console.WriteLine("-- Usando Enumerable.GroupBy-- \n"); Console.WriteLine("-- Verificar número duplicado na lista --\n"); List<int> lista = new List<int>() { 5, -1, 4, 5, 9, -1, 8 , 7, -4, 15, 19, 2, 9}; List<int> resultado = lista.GroupBy(x => x) Console.WriteLine("Números duplicados na lista"); Console.WriteLine("\nlista:\n"); Console.ReadLine();
|
Neste exemplo , dada uma lista, será retornado os números duplicados.
Resultado da execução :
Podemos usar também o método Enumerable.SelectMany(). No entanto, para obter todas as duplicatas distintas, considere aplicar o método Distinct() à sequência resultante.
List<int> lista = new List<int>() { 5, -1, 4, 5, 9, -1, 8, 5, 4, 7 };
var duplicados = lista.GroupBy(x => x) Console.WriteLine("Números duplicados na lista"); Console.WriteLine("\nlista:\n");
|
Neste cenário é que entra em cena o padrão Null Object.
Usando Set
Usando outra abordagem podemos usar Set onde a ideia é iterar sobre a lista e acompanhar todos os itens em um HashSet. Se um item for encontrado antes, marque-o como duplicado e relate todos os itens duplicados no final do loop.
List<int> lista = new List<int>() { 5, -1, 4, 5, 9, -1, 8, 4 };
var conjunto = new HashSet<int>(); Console.WriteLine("Números duplicados na lista"); Console.WriteLine("\nlista:\n");
|
Temos assim algumas abordagens que podemos usar para verificar se existem números duplicados em uma lista.
Pegue o código aqui: ProcuraItensDuplicados.zip
"Ele (Jesus) deu a si mesmo por nós, a
fim de nos remir de toda iniquidade e purificar, para si mesmo, um povo
exclusivamente seu, dedicado à prática de boas obras."
Tito 2:14
Referências: