saber posicion numeros numero mayor los existe encontrar elementos elemento comparar como buscar arreglo array c# linq list equality

posicion - numero mayor de un arreglo c#



¿Cuál es la mejor manera de verificar que las listas<T> de la Lista sean iguales en C#? (6)

Hay muchas formas de hacer esto, pero siento que me he perdido una función o algo.

Obviamente, la List == List utilizará Object.Equals() y devolverá false .

Si todos los elementos de la lista son iguales y están presentes en la misma ubicación en la lista opuesta, los consideraría iguales. Estoy usando tipos de valor, pero un objeto de datos correctamente implementado debería funcionar de la misma manera (es decir, no estoy buscando una lista copiada poco profunda, solo que el valor de cada objeto es el mismo).

He intentado buscar y hay preguntas similares, pero mi pregunta es una igualdad de todos los elementos, en un orden exacto.


Junté esta variación:

private bool AreEqual<T>(List<T> x, List<T> y) { // same list or both are null if (x == y) { return true; } // one is null (but not the other) if (x== null || y == null) { return false; } // count differs; they are not equal if (x.Count != y.Count) { return false; } for (int i = 0; i < x.Count; i++) { if (!x[i].Equals(y[i])) { return false; } } return true; }

El nerd en mí también se arrastró, así que hice una prueba de rendimiento contra SequenceEquals, y esta tiene una ligera ventaja.

Ahora, la pregunta para hacer; ¿Merece la pena este pequeño, casi medible aumento de rendimiento agregar el código a la base de código y mantenerlo? Lo dudo mucho; o)


La mala implementación es

if (List1.Count == List2.Count) { for(int i = 0; i < List1.Count; i++) { if(List1[i] != List2[i]) { return false; } } return true; } return false;


Toqué un método de extensión rápida:

namespace ExtensionMethods { public static class MyExtensions { public static bool Matches<T>(this List<T> list1, List<T> list2) { if (list1.Count != list2.Count) return false; for (var i = 0; i < list1.Count; i++) { if (list1[i] != list2[i]) return false; } return true; } } }


Uno puede escribir un propósito general IEqualityComparer<T> para las secuencias. Una simple:

public class SequenceEqualityComparer<T> : IEqualityComparer<IEnumerable<T>> { public bool Equals(IEnumerable<T> x, IEnumerable<T> y) { return x.SequenceEqual(y); } public int GetHashCode(IEnumerable<T> obj) { return unchecked(obj.Aggregate(397, (x, y) => x * 31 + y.GetHashCode())); } }

Una versión más completa : que debería tener un mejor rendimiento.

public class SequenceEqualityComparer<T> : EqualityComparer<IEnumerable<T>>, IEquatable<SequenceEqualityComparer<T>> { readonly IEqualityComparer<T> comparer; public SequenceEqualityComparer(IEqualityComparer<T> comparer = null) { this.comparer = comparer ?? EqualityComparer<T>.Default; } public override bool Equals(IEnumerable<T> x, IEnumerable<T> y) { // safer to use ReferenceEquals as == could be overridden if (ReferenceEquals(x, y)) return true; if (x == null || y == null) return false; var xICollection = x as ICollection<T>; if (xICollection != null) { var yICollection = y as ICollection<T>; if (yICollection != null) { if (xICollection.Count != yICollection.Count) return false; var xIList = x as IList<T>; if (xIList != null) { var yIList = y as IList<T>; if (yIList != null) { // optimization - loops from bottom for (int i = xIList.Count - 1; i >= 0; i--) if (!comparer.Equals(xIList[i], yIList[i])) return false; return true; } } } } return x.SequenceEqual(y, comparer); } public override int GetHashCode(IEnumerable<T> sequence) { unchecked { int hash = 397; foreach (var item in sequence) hash = hash * 31 + comparer.GetHashCode(item); return hash; } } public bool Equals(SequenceEqualityComparer<T> other) { if (ReferenceEquals(null, other)) return false; if (ReferenceEquals(this, other)) return true; return this.comparer.Equals(other.comparer); } public override bool Equals(object obj) { return Equals(obj as SequenceEqualityComparer<T>); } public override int GetHashCode() { return comparer.GetHashCode(); } }

Esto tiene algunas características:

  1. La comparación se realiza de abajo hacia arriba. Hay más probabilidad de que las colecciones difieran al final en los casos de uso típicos.

  2. Se puede IEqualityComparer<T> un IEqualityComparer<T> para basar la comparación de los elementos de la colección.


Use linq SequenceEqual para verificar la igualdad de secuencia porque el método Equals verifica la igualdad de referencia.

bool isEqual = list1.SequenceEqual(list2);

El método SequenceEqual() toma una segunda secuencia I Enumerable<T> como parámetro y realiza una comparación, elemento por elemento , con la secuencia objetivo (primera). Si las dos secuencias contienen el mismo número de elementos, y cada elemento en la primera secuencia es igual al elemento correspondiente en la segunda secuencia (usando el comparador de igualdad predeterminado ), entonces SequenceEqual() returns true . De lo contrario, se devuelve false .

O si no te importa el orden de los elementos, utiliza el método Enumerable.All :

var isEqual = list1.All(list2.Contains);

La segunda versión también requiere otra comprobación para el recuento porque devolvería verdadero incluso si list2 contiene más elementos que list1 .


Enumerable.SequenceEqual<TSource>

MSDN