sort property generic ejemplos desc ascending array c# sorting icomparer

property - order by list c# linq



Usando IComparer para clasificar (4)

Estoy tratando de usar un IComparer para ordenar una lista de puntos. Aquí está la clase de IComparer:

public class CoordinatesBasedComparer : IComparer { public int Compare(Object q, Object r) { Point a = (p)q; Point b = (p)r; if ((a.x == b.x) && (a.y == b.y)) return 0; if ((a.x < b.x) || ((a.x == b.x) && (a.y < b.y))) return -1; return 1; } }

En el código del cliente, estoy tratando de usar esta clase para ordenar una lista de puntos p (de tipo List<Point> ):

CoordinatesBasedComparer c = new CoordinatesBasedComparer(); Points.Sort(c);

Los errores del código hacia fuera. Aparentemente, se espera que IComparer<Point> sea ​​un argumento para ordenar el método.
¿Qué necesito hacer para arreglar esto?


Es necesario implementar la interfaz de tipo fuerte ( MSDN ).

public class CoordinatesBasedComparer : IComparer<Point> { public int Compare(Point a, Point b) { if ((a.x == b.x) && (a.y == b.y)) return 0; if ((a.x < b.x) || ((a.x == b.x) && (a.y < b.y))) return -1; return 1; } }

Por cierto, creo que usas demasiadas llaves, creo que deberían usarse solo cuando contribuyen al compilador. Esta es mi versión:

if (a.x == b.x && a.y == b.y) return 0; if (a.x < b.x || (a.x == b.x && a.y < b.y)) return -1;

Igual que no me gusta la gente que usa return (0) .

Tenga en cuenta que si apunta a una aplicación .Net-3.5 + puede usar LINQ, que es más fácil e incluso más rápido con la clasificación.

La versión LINQ puede ser algo como:

var orderedList = Points.OrderBy(point => point.x) .ThenBy(point => point.y) .ToList();


Si eres lento como yo, el -1 y 1 pueden ser difíciles de razonar al usar IComparer . La forma de pensarlo es cuando x debería ir primero, devuelve -1. Cuando y debe ir primero, devuelve 1.

Todavía puede ser confuso si tiene muchos campos por ordenar. Puede usar un Enum para hacer que su lógica de comparación sea más legible que 1 y -1, luego emita el resultado.

Este ejemplo coloca los objetos con la menor cantidad de campos nulos en el frente.

public class NullishObjectsToTheBackOfTheLine: IComparer<ClassToCompare> { private enum Xy { X = -1, Both = 0, Y = 1 }; //the IComparer implementation wraps your readable code in an int cast. public int Compare(ClassToCompare x, ClassToCompare y) { return (int) CompareXy(x, y); } private static Xy CompareXy(ClassToCompare x, ClassToCompare y) { if (x == null && y == null) return Xy.Both; //put any nulls at the end of the list if (x == null) return Xy.Y; if (y == null) return Xy.X; if (x.Country == y.Country && x.ProductId == y.ProductId) return Xy.Both; //put the least amount of at the front if (x.ProductId == null && x.Country == null) return Xy.Y; if (y.ProductId == null && y.Country == null) return Xy.X; //put the country values that are not nulls in front if (x.Country != y.Country) return x.Country != null ? Xy.X : Xy.Y; //if we got this far, one of these has a null product id and the other doesn''t return x.ProductId != null ? Xy.X : Xy.Y; } } public class ClassToCompare { public string Country { get; set; } public string ProductId { get; set; } }


InvalidOperation un error de InvalidOperation al agregar un objeto de tipo MyClass a una lista SortedList<MyClass> . Estaba, incorrectamente, implementando la interfaz de IComparer. Lo que necesitaba implementar era IComparable con el método CompareTo (MyClass other), en lugar de ICompare.Compare (MyClass x, MyClass y). Este es un ejemplo simplificado:

SortedList<MyClass> sortedList = new SortedList<MyClass>(); MyClass a=new MyClass(), b=new MyClass(); sortedList.Add(a); sortedList.Add(b); // Note, sort only happens once second element is added

Esto lo arregló :

public class MyClass : IComparable<MyClass> { int IComparable<MyClass>.CompareTo(MyClass other) { // DoCompareFunction(this, other); and return -1,0,1 } }

Esto se rompió (no haga esto si agrega a SortedList<MyClass> ) :

public class MyClass : IComparer<MyClass> { int IComparable<MyClass>.Compare(MyClass x, MyClass y) { // DoCompareFunction(x, y); and return -1,0,1 } }

Este fue el error:

Error al comparar dos elementos en la matriz.
en System.Collections.Generic.ArraySortHelper`1.BinarySearch (T [] array, índice Int32, longitud Int32, valor T, comparador IComparer`1)
en System.Array.BinarySearch [T] (T [] array, índice Int32, longitud Int32, valor T, comparador IComparer`1)
en System.Collections.Generic.SortedList`2.Add (tecla TKey, valor de TValue)


public class CoordinatesBasedComparer : IComparer, IComparer<Point> { public int Compare(Point a, Point b) { if ((a.x == b.x) && (a.y == b.y)) return 0; if ((a.x < b.x) || ((a.x == b.x) && (a.y < b.y))) return -1; return 1; } int IComparer.Compare(Object q, Object r) { return Compare((Point)q, (Point)r); } }