安定ソートは、同じ値を持つ要素の相対的な順序を維持するソートです。
ArrayList.Sortのドキュメントによると、IComparer
が提供されている場合、並べ替えは安定しています。
comparerがnullに設定されている場合、このメソッドは比較ソート(不安定ソートとも呼ばれます)を実行します。つまり、2つの要素が等しい場合、それらの順序は保持されない可能性があります。対照的に、安定ソートでは、等しい要素の順序が保持されます。安定したソートを実行するには、カスタムIComparerインターフェースを実装する必要があります。
何かが足りない場合を除いて、次のテストケースはArrayList.Sort
、安定ソートを使用していないことを示しています。
internal class DisplayOrdered {
public int ID { get; set; }
public int DisplayOrder { get; set; }
public override string ToString() {
return string.Format("ID: {0}, DisplayOrder: {1}", ID, DisplayOrder);
}
}
internal class DisplayOrderedComparer : IComparer {
public int Compare(object x, object y) {
return ((DisplayOrdered)x).DisplayOrder - ((DisplayOrdered)y).DisplayOrder;
}
}
[TestFixture]
public class ArrayListStableSortTest {
[Test]
public void TestWeblinkCallArrayListIsSortedUsingStableSort() {
var call1 = new DisplayOrdered {ID = 1, DisplayOrder = 0};
var call2 = new DisplayOrdered {ID = 2, DisplayOrder = 0};
var call3 = new DisplayOrdered {ID = 3, DisplayOrder = 2};
var list = new ArrayList {call1, call2, call3};
list.Sort(new DisplayOrderedComparer());
// expected order (by ID): 1, 2, 3 (because the DisplayOrder
// is equal for ID's 1 and 2, their ordering should be
// maintained for a stable sort.)
Assert.AreEqual(call1, list[0]); // Actual: ID=2 ** FAILS
Assert.AreEqual(call2, list[1]); // Actual: ID=1
Assert.AreEqual(call3, list[2]); // Actual: ID=3
}
}
私は何かが足りないのですか?そうでない場合、これはドキュメントのバグですか、それともライブラリのバグですか?
どうやらLinqでOrderByを使用すると、安定したソートが得られます。