Qual é a maneira mais rápida de determinar se um IEnumerable contém todos os elementos de outro IEnumerable ao comparar um campo / propriedade de cada elemento em ambas as coleções?
public class Item
{
public string Value;
public Item(string value)
{
Value = value;
}
}
//example usage
Item[] List1 = {new Item("1"),new Item("a")};
Item[] List2 = {new Item("a"),new Item("b"),new Item("c"),new Item("1")};
bool Contains(IEnumerable<Item> list1, IEnumerable<Item>, list2)
{
var list1Values = list1.Select(item => item.Value);
var list2Values = list2.Select(item => item.Value);
return //are ALL of list1Values in list2Values?
}
Contains(List1,List2) // should return true
Contains(List2,List1) // should return false
c#
.net
linq
ienumerable
Brandon Zacharie
fonte
fonte
Respostas:
Não existe uma "maneira rápida" de fazer isso, a menos que você rastreie e mantenha algum estado que determine se todos os valores em uma coleção estão contidos em outra. Se você só tiver
IEnumerable<T>
que trabalhar contra, eu usariaIntersect
.O desempenho deste deve ser muito razoável, já
Intersect()
que enumerará sobre cada lista apenas uma vez. Além disso, a segunda chamada paraCount()
será ideal se o tipo subjacente for um emICollection<T>
vez de apenas umIEnumerable<T>
.fonte
Você também pode usar Except para remover da primeira lista todos os valores que existem na segunda lista e, em seguida, verificar se todos os valores foram removidos:
Esse método tinha a vantagem de não exigir duas chamadas para Count ().
fonte
C # 3.5+
Usando
Enumerable.All<TSource>
para determinar se todos os itens da Lista2 estão contidos na Lista1:Isso também funcionará quando a lista1 contiver ainda mais do que todos os itens da lista2.
fonte
Contains()
chamada dentro de umaAll()
chamada.bool hasAll = list2Uris.All(list1Uris.Contains);
A resposta de Kent é boa e curta, mas a solução que ele fornece sempre requer iteração em toda a primeira coleção. Aqui está o código-fonte:
Isso nem sempre é necessário. Então, aqui está minha solução:
Na verdade, você deve pensar em usar
ISet<T>
(HashSet<T>
). Ele contém todos os métodos de definição necessários.IsSubsetOf
no seu caso.fonte
o operador Linq SequenceEqual também funcionaria (mas é sensível aos itens do enumerável estarem na mesma ordem)
fonte
A solução marcada como resposta falhará no caso de repetições. Se seu IEnumerable contiver apenas valores distintos, ele será aprovado.
A resposta abaixo é para 2 listas com repetições:
fonte
Você deve usar HashSet em vez de Array.
Exemplo:
Referência
A única limitação do HasSet é que não podemos obter item por índice como Lista, nem obter item por Chave como Dicionários. Tudo que você pode fazer é enumerá-los (para cada um, enquanto, etc.)
Por favor, deixe-me saber se isso funciona para você
fonte
você pode usar este método para comparar duas listas
fonte