A stable sort es un tipo que mantiene el orden relativo de los elementos con el mismo valor.ArrayList.Sort debe ser un tipo estable con un IComparer pero no lo es?
Los documentos sobre ArrayList.Sort dicen que cuando se proporciona un IComparer
el tipo es estable:
Si comparador se pone a cero, este método realiza una comparación de orden (también llamado un tipo inestable); es decir, si dos elementos son iguales, es posible que su orden no se conserve. Por el contrario, un género estable conserva el orden de los elementos que son iguales. Para realizar una clasificación estable, debe implementar una interfaz IComparer personalizada.
A menos que me falta algo, el siguiente caso de prueba muestra que ArrayList.Sort
no está utilizando una especie estable:
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
}
}
Me estoy perdiendo algo? De lo contrario, ¿se trataría de un error de documentación o de una biblioteca?
Al parecer, utilizando un OrderBy en Linq da un tipo estable.
¿Es posible que la intención del comentario sea "necesita implementar su propio IComparer que fuerce la clasificación para ser estable" y no "si implementa su propio IComparer, el género será estable implícitamente"? – BlueMonkMN
Esa no es una buena manera de implementar Compare. http://blogs.msdn.com/b/ericlippert/archive/2011/01/27/spot-the-defect-bad-comparisons-part-three.aspx –
¿Estás seguro de que no estás cayendo en la falacia descrita? aquí: http://blogs.msdn.com/b/ericlippert/archive/2011/01/27/spot-the-defect-bad-comparisons-part-three.aspx EDIT: Bah, fue golpeado al golpe al intentarlo para encontrar el enlace. : D –