Estou procurando uma maneira muito rápida de filtrar uma coleção em c #. Atualmente, estou usando coleções genéricas de List <object>, mas estou aberto a usar outras estruturas se elas tiverem melhor desempenho.
Atualmente, estou apenas criando uma nova lista <object> e fazendo um loop pela lista original. Se os critérios de filtragem corresponderem, coloco uma cópia na nova lista.
Existe uma maneira melhor de fazer isso? Existe uma maneira de filtrar no local para que não seja necessária uma lista temporária?
c#
collections
filtering
Jason Z
fonte
fonte
Respostas:
Se você estiver usando o C # 3.0, poderá usar o linq, muito melhor e muito mais elegante:
Se você não encontrar o
.Where
, significa que precisa importarusing System.Linq;
na parte superior do seu arquivo.fonte
.Where(predefinedQuery)
vez de usar.Where(x => x > 7)
?public bool predefinedQuery(int x) { return x > 7; }
. Então o seu.Where(predefinedQuery)
funcionaria bem.Aqui está um bloco de código / exemplo de alguma filtragem de lista usando três métodos diferentes que reuni para mostrar a filtragem de lista baseada em Lambdas e LINQ.
fonte
List<T>
tem umFindAll
método que fará a filtragem para você e retornará um subconjunto da lista.O MSDN tem um ótimo exemplo de código aqui: http://msdn.microsoft.com/en-us/library/aa701359(VS.80).aspx
Edição: Eu escrevi isso antes que eu tivesse uma boa compreensão do LINQ e do
Where()
método. Se eu escrevesse isso hoje, provavelmente usaria o método que Jorge menciona acima. OFindAll
método ainda funciona se você estiver preso em um ambiente .NET 2.0.fonte
Você pode usar IEnumerable para eliminar a necessidade de uma lista temporária.
onde Matches é o nome do seu método de filtro. E você pode usar isso como:
Isso chamará a função GetFilteredItems quando necessário e, em alguns casos, se você não usar todos os itens da coleção filtrada, poderá fornecer um bom ganho de desempenho.
fonte
Para fazer isso no lugar, você pode usar o método RemoveAll da classe "List <>" junto com uma classe personalizada "Predicate" ... mas tudo o que faz é limpar o código ... sob o capô, ele está fazendo o mesmo coisa que você é ... mas sim, ele faz no lugar, então você faz o mesmo na lista temporária.
fonte
Você pode usar o método FindAll da lista, fornecendo um representante para filtrar. No entanto, concordo com o @ IainMH que não vale a pena se preocupar muito, a menos que seja uma lista enorme.
fonte
Ou, se preferir, use a sintaxe de consulta especial fornecida pelo compilador C # 3:
fonte
O uso do LINQ é relativamente mais lento do que o uso de um predicado fornecido ao
FindAll
método Lists . Também tenha cuidado com o LINQ, pois a enumeração dolist
não é realmente executada até você acessar o resultado. Isso pode significar que, quando você acha que criou uma lista filtrada, o conteúdo pode diferir do que você esperava quando realmente a leu.fonte
Se sua lista for muito grande e você estiver filtrando repetidamente - você pode classificar a lista original no atributo filter, pesquisa binária para encontrar os pontos inicial e final.
Hora inicial O (n * log (n)) e O (log (n)).
A filtragem padrão leva O (n) de cada vez.
fonte