2009-05-20 16 views
4

iComparerを持つオブジェクトの2つの値を使用してリストをソートすることはできますか?複数値のIComparer

value1に基づいて並べ替えるカスタムの比較クラスがあります。しかし、value1とvalue2をソートするにはどうすればよいでしょうか?

リストをvalue2でソートすると、value1は機能しますか?

答えて

12

IComparerクラスで処理する必要があります。たとえば:

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

素晴らしい! – steve

+0

私はいつもウェイトを使い、3つのアイテムすべてを比較することでこれをやってきました。このようにすることは決して考えなかった、それは単純すぎると思う; – AlexCuse

0

あなたがあなた自身の比較演算を実装する場合は、あなたが望む任意の並べ替えを実行することができます

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

は今、上記のコードは、たIComparerクラスではなく、比較のアプローチは同じです。

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

エンジニアリングの印象的な偉業。 – mquander

+0

@mquander:皮肉は不適切です。 –