2010-03-24 4 views
5

Ho una lista in cui elemento è:List <> proprio operatore di confronto

struct element { 
       double priority; 
       int value; 
       } 

Come posso implementare il mio operatore di confronto che mi permetterà Ordina lista per priorità? Provo con SortredList ... ma non permetto chiavi douplicated :(

Un grande grazie per l'aiuto

+0

Quale linguaggio di programmazione? –

+0

C#? Giava? Che lang? –

+2

probabilmente C#, a causa della sintassi <> generica/template, C++ non ha niente di incorporato chiamato esattamente 'List', e Java preferirebbe ArrayList. –

risposta

3

Se non è possibile fare affidamento su C# 3 estensioni o lambda allora si può avere la struct implementi l'interfaccia IComparable, in questo modo:

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 
} 

ci sono anche un typesafe version di questa interfaccia, ma il principio è lo stesso

Dopo aver che interfaccia implementata sul vostro struct o classe, chiamando il metodo Sort su List<> sarà "solo lavoro"

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

Anche in 2.0 è possibile utilizzare l'approccio metodo anonimo, però. –

+0

Grande implementazione! Grazie per l'esempio di esempio;) Questo è quello che mi serve! :) – netmajor

+0

Marc: sì, hai ragione. Un vantaggio di questo approccio è che funziona automaticamente per tutti i luoghi in cui qualcuno ha bisogno di ordinare una collezione di 'element's. –

11

Supponendo C# 3 o versione successiva:!

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

Vale la pena sottolineare che ciò restituirà un nuovo 'IEnumerable <>' invece di ordinare l'esistente 'Elenco <>' sul posto. – LukeH

+1

Si noti che questo non verrà ordinato l'elenco, restituirà un elenco ordinato elemento per elemento quando viene ripetuto. – Blindy

+0

Penso di più al metodo Sort che manipola la raccolta e salva i risultati. Ma anche Tnx per questo! Mi piace il tuo aiuto :) – netmajor

1

Se si desidera ordinare l'elenco per sé senza creare una nuova istanza, è possibile implementare IComparer, quindi chiamare list.sort con un'istanza dell'implementazione

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

... con 'lanciare la nuova NotImplementedException();' sostituita con 'return x.priority.CompareTo (y.priority);'! :) – gehho

+0

Senza commenti gehho La tua risposta è parziale .. – netmajor

8

È possibile eseguire una sorta sul posto utilizzando la Sort overload che prende un Comparison<T> delegato:

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

Per le versioni precedenti di C# avrete bisogno di scambiare la lambda per la vecchia scuola delegato sintassi:

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

Mi piace questo esempio di classificazione in due scuole! – netmajor

+0

Non riesco a far funzionare il suggerimento lamda? Sto usando 3.5, dice che non può risolvere il simbolo CompareTo – Robs

+1

Lucifer: probabilmente a causa di 'priority' che è un membro privato della struttura' element' –

2

Questo dipende se si desidera ordinare l'elenco stesso o recuperare i valori in ordine (senza modificare l'elenco).

Per ordinare l'elenco stesso (supponendo di avere un List<element> chiamato elements):

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

NET 2.0 equivalenti:

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

per ottenere i valori in modo ordinato:

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

Non c'è un equivalente LINQ in .NET 2.0, ma è possibile scrivere il proprio:

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; 
} 

Usage:

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

Bella compilation di tutte le risposte: P – netmajor