Tengo la siguiente situación
class Person
{
string Name;
int Value;
int Change;
}
List<Person> list1;
List<Person> list2;
Necesito combinar las 2 listas en una nueva List<Person>
en caso de que sea la misma persona que el registro combinado tendría ese nombre, el valor de la persona en list2, el cambio sería el valor de list2, el valor de list1. El cambio es 0 si no hay duplicado
Respuestas:
Esto se puede hacer fácilmente utilizando el método de extensión Linq Union. Por ejemplo:
Esto devolverá una Lista en la que se fusionan las dos listas y se eliminan los dobles. Si no especifica un comparador en el método de extensión Union como en mi ejemplo, utilizará los métodos predeterminados Equals y GetHashCode en su clase Person. Si, por ejemplo, desea comparar personas comparando su propiedad Nombre, debe anular estos métodos para realizar la comparación usted mismo. Verifique el siguiente ejemplo de código para lograr eso. Debe agregar este código a su clase de Persona.
Si no desea establecer el método Equals predeterminado de su clase Persona para usar siempre el Nombre para comparar dos objetos, también puede escribir una clase comparadora que use la interfaz IEqualityComparer. Luego puede proporcionar este comparador como el segundo parámetro en el método de Unión de extensión de Linq. Puede encontrar más información sobre cómo escribir un método de comparación en http://msdn.microsoft.com/en-us/library/system.collections.iequalitycomparer.aspx
fuente
Union
conIntersect
?Concat
que no combina duplicadosNoté que esta pregunta no se marcó como respondida después de 2 años; creo que la respuesta más cercana es Richards, pero se puede simplificar bastante a esto:
Aunque esto no fallará en el caso de que tenga nombres duplicados en cualquier conjunto.
Algunas otras respuestas han sugerido el uso de la unión; definitivamente, este no es el camino a seguir, ya que solo obtendrá una lista distinta, sin hacer la combinación.
fuente
¿Por qué no solo usas
Concat
?Concat es parte de linq y es más eficiente que hacer un
AddRange()
en tu caso:
fuente
Actually, due to deferred execution, using Concat would likely be faster because it avoids object allocation - Concat doesn't copy anything, it just creates links between the lists so when enumerating and you reach the end of one it transparently takes you to the start of the next!
este es mi punto.Este es linq
Esto es Normaly (AddRange)
Esta es Normaly (Foreach)
Esta es Normaly (Foreach-Dublice)
fuente
Hay algunas piezas para hacer esto, suponiendo que cada lista no contenga duplicados, Nombre es un identificador único y ninguna de las listas está ordenada.
Primero cree un método de extensión anexa para obtener una lista única:
Por lo tanto, puede obtener una sola lista:
Luego agrupe por nombre
Luego puede procesar cada grupo con un ayudante para procesar un grupo a la vez
Que se puede aplicar a cada elemento de
grouped
:(Advertencia: no probado).
fuente
Append
es un duplicado casi exacto de la lista para usarConcat
.Enumerable.Concat
y, por lo tanto, la volví a implementar.Necesita algo como una unión externa completa. System.Linq.Enumerable no tiene ningún método que implemente una combinación externa completa, por lo que debemos hacerlo nosotros mismos.
fuente
¿El siguiente código funciona para su problema? He usado un foreach con un poco de linq adentro para hacer la combinación de listas y asumí que las personas son iguales si sus nombres coinciden, y parece que imprime los valores esperados cuando se ejecuta. Resharper no ofrece ninguna sugerencia para convertir el foreach en linq, por lo que probablemente sea tan bueno como lo hará de esta manera.
fuente
fuente