2010-03-24 29 views
5

Tengo una lista en donde el elemento es:List <> propia comparador

struct element { 
       double priority; 
       int value; 
       } 

¿Cómo puedo aplicar mi propio comparador que me permitirá ordenar la lista por orden de prioridad? Trato con SortredList ... pero no permito teclas douplicated :(

muchas gracias por la ayuda

+0

¿Qué lenguaje de programación? –

+0

C#? ¿Java? ¿Qué Lang? –

+2

probablemente C#, debido a la <> sintaxis genérica/plantilla, C++ no tiene nada incorporado llamado exactamente 'Lista', y Java preferiría ArrayList. –

Respuesta

3

Si no puede depender de C# 3 extensiones o Lambdas entonces usted puede tener su estructura implementa la interfaz IComparable, así:

struct element : IComparable 
{ 
    double priority; 
    int value; 
    public element(int val, double prio) 
    { 
     priority = prio; 
     value = val; 
    } 
    #region IComparable Members 

    public int CompareTo(object obj) 
    { 
     // throws exception if type is wrong 
     element other = (element)obj; 
     return priority.CompareTo(other.priority); 
    } 

    #endregion 
} 

Hay también un typesafe version de esta interfaz, pero el principio es el mismo

Una vez que haya esa interfaz implementada en su estructura o clase, llamando al método Sort en List<> voluntad "sólo trabajo"

static void Main(string[] args) 
{ 
    Random r = new Random(); 
    List<element> myList = new List<element>(); 
    for (int i = 0; i < 10; i++) 
     myList.Add(new element(r.Next(), r.NextDouble())); 
    // List is now unsorted 
    myList.Sort(); 
    // List is now sorted by priority 
    Console.ReadLine(); 
} 
+0

Incluso en 2.0 puedes usar el método de método anónimo. –

+0

¡Gran implementación! Gracias por el ejemplo de uso;) ¡Esto es lo que necesito! :) – netmajor

+0

Marc: si, tienes razón. Sin embargo, un beneficio de este enfoque es que funciona automáticamente para todos los lugares donde alguien necesita ordenar una colección de 'elementos'. –

11

Suponiendo C# 3 o posterior:

var sorted = MyList.OrderBy(e => e.priority); 
+0

Vale la pena señalar que esto devolverá un nuevo 'IEnumerable <>' en lugar de ordenar el 'List <>' existente en el sitio. – LukeH

+1

Tenga en cuenta que esto no ordenará la lista, sino que devolverá un elemento de lista ordenada por elemento cuando se repita. – Blindy

+0

Estoy más pensando en el método Sort que manipula la colección y guarda el resultado. Pero Tnx por esto también! Agradezco su ayuda :) – netmajor

1

Si desea ordenar la lista en sí, sin crear una nueva instancia, se puede implementar IComparer, a continuación, llamar list.sort con una instancia de la implementación

public class ElementComparer : IComparer<element> 
{ 
    public int Compare(element x, element y) 
    { 
     throw new NotImplementedException(); 
    } 
} 
+1

... con 'throw new NotImplementedException();' reemplazado por 'return x.priority.CompareTo (y.priority);'! :) – gehho

+0

Sin gehho comment Tu respuesta es parcial .. – netmajor

8

se puede realizar una especie en el lugar mediante el uso de la Sort overload que toma un Comparison<T> delegado:

yourList.Sort((x, y) => x.priority.CompareTo(y.priority)); 

Para versiones anteriores de C# que necesitará para intercambiar el lambda de la vieja escuela sintaxis delegado:

yourList.Sort(
    delegate(element x, element y) { return x.priority.CompareTo(y.priority); }); 
+0

¡Me gusta mucho este ejemplo de dos escuelas! – netmajor

+0

No puedo obtener la sugerencia de lamda para que funcione? Estoy usando 3.5, dice que no puede resolver el símbolo CompareTo – Robs

+1

Lucifer: probablemente debido a que 'priority' es un miembro privado de la estructura' element' –

2

Esto depende de si desea ordenar la lista o recuperar los valores en orden ordenado (sin cambiar la lista).

Para ordenar la lista en sí (suponiendo que tiene una llamada List<element>elements):

elements.Sort((x, y) => x.priority.CompareTo(y.priority)); 
// now elements is sorted 

.NET 2.0 equivalentes:

elements.Sort(
    delegate(element x, element y) { 
     return x.priority.CompareTo(y.priority); 
    } 
); 

para obtener los valores en el orden establecido:

var orderedElements = elements.OrderBy(x => x.priority); 
// elements remains the same, but orderedElements will retrieve them in order 

No hay equivalente LINQ en .NET 2.0, pero puede escribir el suyo:

public static IEnumerable<T> OrderBy<T>(IEnumerable<T> source, Comparison<T> comparison) { 
    List<T> copy = new List<T>(source); 
    copy.Sort(comparison); 

    foreach (T item in copy) 
     yield return item; 
} 

Uso:

Comparison<element> compareByPriority = delegate(element x, element y) { 
    return x.priority.CompareTo(y.priority); 
}; 

// unfortunately .NET 2.0 doesn't support extension methods, so this has to be 
// expressed as a regular static method 
IEnumerable<element> orderedElements = OrderBy(elements, compareByPriority); 
+0

Buena compilación de todas las respuestas: P – netmajor

Cuestiones relacionadas