¿Cuál es la forma más rápida de determinar si un IEnumerable contiene todos los elementos de otro IEnumerable al comparar un campo / propiedad de cada elemento en ambas colecciones?
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
fuente
fuente
Respuestas:
No existe una "forma rápida" de hacer esto a menos que realice un seguimiento y mantenga algún estado que determine si todos los valores de una colección están contenidos en otra. Si solo tienes
IEnumerable<T>
que trabajar en contra, usaríaIntersect
.El rendimiento de este debe ser muy razonable, ya que
Intersect()
se enumerará sobre cada lista una sola vez. Además, la segunda llamada aCount()
será óptima si el tipo subyacente es un enICollection<T>
lugar de solo unIEnumerable<T>
.fuente
También puede usar Excepto para eliminar de la primera lista todos los valores que existen en la segunda lista y luego verificar si se han eliminado todos los valores:
Este método tenía la ventaja de no requerir dos llamadas a Count ().
fuente
C # 3.5+
Utilizando
Enumerable.All<TSource>
para determinar si todos los elementos de List2 están contenidos en List1:Esto también funcionará cuando list1 contenga incluso más que todos los elementos de list2.
fuente
Contains()
llamada dentro de unaAll()
llamada!bool hasAll = list2Uris.All(list1Uris.Contains);
La respuesta de Kent es buena y breve, pero la solución que proporciona siempre requiere iteración sobre toda la primera colección. Aquí está el código fuente:
Eso no siempre es obligatorio. Entonces, aquí está mi solución:
En realidad, deberías pensar en usar
ISet<T>
(HashSet<T>
). Contiene todos los métodos de configuración necesarios.IsSubsetOf
en tu caso.fuente
el operador de Linq SequenceEqual también funcionaría (pero es sensible a que los elementos del enumerable estén en el mismo orden)
fuente
La solución marcada como la respuesta fallaría en el caso de repeticiones. Si su IEnumerable solo contiene valores distintos, pasará.
La siguiente respuesta es para 2 listas con repeticiones:
fuente
Debería utilizar HashSet en lugar de Array.
Ejemplo:
Referencia
La única limitación de HasSet es que no podemos obtener elemento por índice como Lista ni obtener elemento por clave como Diccionarios. Todo lo que puede hacer es enumerarlos (para cada uno, mientras, etc.)
Por favor, avíseme si eso funciona para usted
fuente
puede utilizar este método para comparar dos listas
fuente