2009-05-20 15 views
4

Ist es möglich, eine Liste mit zwei Werten in einem Objekt mit iComparer zu sortieren?IComparer auf mehreren Werten

Ich habe eine benutzerdefinierte Vergleichsklasse, die basierend auf Wert1 sortiert. Aber was ist der beste Weg, um eine Sortierung von Wert1 und Wert2 zu erhalten?

Würde die Liste nach Wert2 sortieren und dann Wert1?

Antwort

12

Ihre IComparer Klasse sollte damit umgehen. Zum Beispiel:

public class ThingComparer : IComparer 
{ 
    public int Compare(object x, object y) 
    { 
     // null- and type-checking omitted for clarity 

     // sort by A, B, and then C 

     if (x.A != y.A) return x.A.CompareTo(y.A); 
     if (x.B != y.B) return x.B.CompareTo(y.B); 
     return x.C.CompareTo(y.C); 
    } 
} 
+0

Großartig! Danke für die schnelle Antwort – steve

+0

Ich habe das immer getan, indem ich Gewichte benutze und alle drei Punkte vergleiche. Ich hätte nie gedacht, dass es so ist, ich denke, es war zu einfach;) – AlexCuse

0

Wenn Sie eine eigene comparer implementieren können Sie jede Art ausführen Sie wollen:

List<Customer> customers = GetCustomers(); 
customers.Sort(delegate(Customer x, Customer y) 
{ 
    if (x.Name != y.Name) 
    { 
     return x.Name.CompareTo(y.Name); 
    } 

    return x.Location.CompareTo(y.Location); 
}); 

nun der obige Code ist nicht eine IComparer-Klasse, aber der Vergleich Ansatz ist die gleiche.

0
public class ScratchComparer : IComparer<Scratch> 
{ 
    public int Compare(Scratch x, Scratch y) 
    { 
     return x.Foo.CompareTo(y.Foo).CompareTo(0.CompareTo(x.Bar.CompareTo(y.Bar))); 
    } 
} 

[TestFixture] 
public class Scratch 
{ 
    public virtual int Foo { get; set; } 
    public virtual int Bar { get; set; } 

    [Test] 
    public void Should_sort() 
    { 
     var scratches = new[] 
     { 
      new Scratch {Foo = 1, Bar = 1}, 
      new Scratch {Foo = 2, Bar = 1}, 
      new Scratch {Foo = 1, Bar = 1}, 
      new Scratch {Foo = 1, Bar = 2} 
     }; 

     // IComparer 
     Array.Sort(scratches, new ScratchComparer()); 

     scratches[0].Foo.ShouldEqual(1); 
     scratches[0].Bar.ShouldEqual(1); 

     scratches[1].Foo.ShouldEqual(1); 
     scratches[1].Bar.ShouldEqual(1); 

     scratches[2].Foo.ShouldEqual(1); 
     scratches[2].Bar.ShouldEqual(2); 

     scratches[3].Foo.ShouldEqual(2); 
     scratches[3].Bar.ShouldEqual(1); 

     // better 
     Scratch[] ordered = scratches.OrderBy(x => x.Foo).ThenBy(x => x.Bar).ToArray(); 

     ordered[0].Foo.ShouldEqual(1); 
     ordered[0].Bar.ShouldEqual(1); 

     ordered[1].Foo.ShouldEqual(1); 
     ordered[1].Bar.ShouldEqual(1); 

     ordered[2].Foo.ShouldEqual(1); 
     ordered[2].Bar.ShouldEqual(2); 

     ordered[3].Foo.ShouldEqual(2); 
     ordered[3].Bar.ShouldEqual(1); 
    } 
} 
+0

Eine beeindruckende Leistung der Technik. – mquander

+0

@Mquander: Ironie ist unangemessen. –

Verwandte Themen