2010-03-18 15 views
13

Ho una classe con 2 stringhe e 1 doppia (quantità).Come si ordina una matrice di classi personalizzate?

classe Donator

  • string name
  • commento stringa
  • quantità doppia

Ora ho un array di Donatori riempito.
Come posso ordinare per importo?

+3

@Jeff Oh no, vuole assolutamente usare 'IndividualHumanBeingWhoDonated' –

+6

Un donatore è un intenditore di ciambelle. – DRBlaise

+1

Duplicati: http://stackoverflow.com/questions/1301822/how-to-sort-an-array-of-object-by-a-specific-field-in-c http://stackoverflow.com/questions/ 1812044/how-to-sort-an-array-of-objects-in-visual-c http: // stackoverflow.it/questions/1211617/sort-an-array-of-typed-objects-based-on-a-property-of-the-object-c –

risposta

22

Se si implementa IComparable<Donator> Si può fare in questo modo:

public class Donator :IComparable<Donator> 
{ 
    public string name { get; set; } 
    public string comment { get; set; } 
    public double amount { get; set; } 

    public int CompareTo(Donator other) 
    { 
    return amount.CompareTo(other.amount); 
    } 
} 

È quindi possibile chiamare specie su quello che vuoi, dicono:

var donors = new List<Donator>(); 
//add donors 
donors.Sort(); 

Il .Sort() chiama il metodo CompareTo() implementato per ordinamento.

C'è anche il lambda alternativo senza IComparable<T>:

var donors = new List<Donator>(); 
//add donors 
donors.Sort((a, b) => a.amount.CompareTo(b.amount)); 
+0

Una classe che implementa IComparer è probabilmente un approccio migliore. – eschneider

+2

@eschneider - Questo è quasi sempre eccessivo per qualcosa di così semplice. Come sarebbe "migliore"? –

+0

È probabile che avranno bisogno di ordinare vari modi. DonorAmountComparer, DonorLastNameComparer, DonorAmountThenLastNameComparer. – eschneider

4

Implementando IComparable e quindi utilizzare Array.Sort.

public class Donator : IComparable { 
    public string name; 
    public string comment; 
    public double amount; 

    public int CompareTo(object obj) { 
     // throws invalid cast exception if not of type Donator 
     Donator otherDonator = (Donator) obj; 

     return this.amount.CompareTo(otherDonator.amount); 
    } 
} 

Donator[] donators; // this is your array 
Array.Sort(donators); // after this donators is sorted 
+0

Potrebbe anche passare un'espressione lambda se non vuole creare una nuova classe –

+0

Provato, ma come ordinare veramente? – Kovu

+1

No in .Net 2.0 non può. – AxelEckenberger

2

Si potrebbe utilizzare MyArray.OrderBy(n => n.Amount) fornendo aver incluso lo spazio dei nomi System.Linq.

+0

Ho provato myArray = myArray.orderby ... l'errore è: Fehler Eine implizite Konvertierung vom Typ "System.Linq.IOrderedEnumerable " in "DongleDonatorSite.Donator []" ist nicht möglich. – Kovu

+0

Utilizzare .ToArray() per trasformare l'enumerable in una matrice. –

+0

Si potrebbe voler aggiungere '.ToArray()' alla fine o cambiare il tipo di variabile a cui si assegna il risultato. A proposito, in molti casi è più pratico (ma non sempre quando le prestazioni sono un problema) smettere di usare gli array e iniziare a usare una lista generica. –

2

Ho sempre utilizzare l'elenco generico, per esempio

List<Donator> MyList; 

allora io chiamo MyList.Sort

MyList.Sort(delegate (Donator a, Donator b) { 
    if (a.Amount < b.Amount) return -1; 
    else if (a.Amount > b.Amount) return 1; 
    else return 0;); 
+0

È uguale a a.Amount.CompareTo (b.Importo) – Ruben

+0

A destra. Inoltre, con il mio metodo, è possibile aggiungere ulteriore logica per ordinare prima per Quantità, poi, Nome se Quantità è uguale, ecc. CompareTo è più semplice per questo caso, e il mio esempio sarebbe utile solo se fosse necessario un ordinamento più interessante logica. –

+0

Penso che ti manchi un ondulato. –

4

Puoi utilizzare anche delegates:

class Program 
{ 
    static void Main(string[] args) 
    { 
     List<Donor> myDonors = new List<Donor>(); 
     // add stuff to your myDonors list... 

     myDonors.Sort(delegate(Donor x, Donor y) { return x.amount.CompareTo(y.amount); }); 
    } 
} 

class Donor 
{ 
    public string name; 
    public string comment; 
    public double amount; 
} 
2

Ecco un ordinamento senza dover implementare un'interfaccia. Questo sta usando un elenco generico

List<Donator> list = new List<Donator>(); 
    Donator don = new Donator("first", "works", 98.0); 
    list.Add(don); 
    don = new Donator("first", "works", 100.0); 
    list.Add(don); 
    don = new Donator("middle", "Yay", 101.1); 
    list.Add(don); 
    don = new Donator("last", "Last one", 99.9); 
    list.Add(don); 
    list.Sort(delegate(Donator d1, Donator d2){ return d1.amount.CompareTo(d2.amount); }); 
0

Un altro modo è quello di creare una classe che implementa IComparer, poi c'è un sovraccarico di passare nella classe Comparer.

http://msdn.microsoft.com/en-us/library/8ehhxeaf.aspx

In questo modo si potrebbe avere diverse classi per ogni sorta specifiche necessarie. Puoi crearne una per ordinare per nome, quantità o altro.

Problemi correlati