2010-03-18 7 views
13

J'ai une classe avec 2 cordes et 1 double (montant).Comment trier un tableau de classes personnalisées?

classe Donator

  • string name
  • commentaire string
  • quantité double

Maintenant, j'ai un tableau de Donateurs rempli.
Comment puis-je trier par montant?

+3

@Jeff Oh non, il veut absolument utiliser 'IndividualHumanBeingWhoDonated' –

+6

Un donateur est un connaisseur de beignets. – DRBlaise

+1

Duplicata: http://stackoverflow.com/questions/1301822/how-to-sort-an-array-of-object-by-a-specific-field-in-c http://stackoverflow.com/questions/ 1812044/comment-trier-un-tableau-d'-objets-en-visuel-c http: // stackoverflow.com/questions/1211617/tri-array-of-strong-typed-objects-based-on-a-property-of-the-object-c –

Répondre

22

Si vous implémentez IComparable<Donator> Vous pouvez le faire comme ceci:

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

Vous pouvez puis trier appel à tout ce que vous voulez, dites:

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

Le .Sort() appelle la méthode CompareTo() vous mis en place pour tri.

Il y a aussi l'alternative lambda sans IComparable<T>:

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

Une classe implémentant IComparer est probablement une meilleure approche. – eschneider

+2

@eschneider - C'est presque toujours exagéré pour quelque chose d'aussi simple. Comment cela serait-il "meilleur"? –

+0

Les chances sont qu'ils devront trier de diverses manières. DonorAmountComparer, DonorLastNameComparer, DonorAmountThenLastNameComparer. – eschneider

4

En mettant en œuvre IComparable, puis utiliser 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

Il pourrait aussi passer une expression lambda s'il ne veut pas créer une nouvelle classe –

+0

essayé, mais comment trier vraiment? – Kovu

+1

Non dans .Net 2.0 il ne peut pas. – AxelEckenberger

2

Vous pouvez utiliser MyArray.OrderBy(n => n.Amount) à condition que vous avez inclus l'espace de noms System.Linq.

+0

J'ai essayé myArray = myArray.orderby ... l'erreur est: Fehler Eine implizite Konvertierung vom Typ "System.Linq.IOrderedEnumerable " dans "DongleDonatorSite.Donator []" ist nicht möglich. – Kovu

+0

Utilisez .ToArray() pour retourner l'énumérable dans un tableau. –

+0

Vous pouvez ajouter '.ToArray()' à la fin ou changer le type de la variable à laquelle vous attribuez le résultat. En passant, dans de nombreux cas, il est plus pratique (mais pas toujours lorsque les performances sont un problème) d'arrêter d'utiliser des tableaux et de commencer à utiliser une liste générique. –

2

J'utilise toujours la liste générique, par exemple

List<Donator> MyList; 

j'appelle 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

Ceci est identique à a.Amount.CompareTo (b.Amount) – Ruben

+0

Right. De plus, avec ma méthode, vous pouvez ensuite ajouter une logique supplémentaire pour trier par Quantité d'abord, puis, Nom si Quantité est la même, etc. CompareTo est plus simple pour ce cas, et mon exemple ne serait utile que si vous aviez besoin d'un tri plus intéressant logique. –

+0

Je pense qu'il vous manque un ondulé. –

4

Vous pouvez utiliser également 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

Voici un tri sans avoir à implémenter une interface. Est d'utiliser une liste générique

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

Une autre façon est de créer une classe qui implémente IComparer, alors il y a une surcharge pour passer dans la classe Comparer.

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

De cette façon, vous pourriez avoir des classes différentes pour chaque type spécifique nécessaire. Vous pouvez en créer un pour trier par nom, montant ou autres.