FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Buscar | Temas de Hoy | Marcar Foros Como Leídos |
|
Herramientas | Buscar en Tema | Desplegado |
#1
|
|||
|
|||
Ordenar e insertar ordenado en TObjectList
Hola a todos.
Me estoy iniciando en Delphi y me gustaría saber como ordenar una lista TObjectList según un campo clave de los objetos insertados en la lista. Leí por algún lado que se dispone del método Sort, pero no tengo claro su utilización. Además me gustaría saber si hay algún método para insertar un objeto de forma ordenada en una lista TObjectList, también con respecto a un campo (propiedad) clave del objeto a insertar. Muchas gracias. Saludos. |
#2
|
||||
|
||||
El método Sort de TObjectList recibe como parámetro una función (que tú defines) que le indica cómo debe comparar tus objetos. La función debe devolver un número positivo si el primer objeto es "mayor" que el primero, 0 si son iguales y un número negativo si el primer objeto es "menor" que el segundo.
Te pongo un ejemplo:
Me parece que TObjectList no tiene forma de insertar ordenadamente. // Saludos |
#3
|
|||
|
|||
Gracias roman por tu respuesta.
Al hacer el llamado con (según tu ejemplo): Cita:
¿Cuál es el problema?. Yo vengo de Pascal estándar, y estoy aprendiendo no hace tanto programación a objetos. Para mi habría que pasarle a la función dos punteros como parámetros, pero en este caso tal vez no sea así. Otra pregunta, ¿ se dispone en Delphi de alguna lista "dinámica" predefinida para insertar objetos de forma ordenada ?. Muchas gracias. Saludos. Última edición por sebamawa fecha: 16-08-2012 a las 19:03:56. |
#4
|
||||
|
||||
No, porque entonces estarías pasando al método Sort el resultado de comparar dos objetos en específico. El parámetro de Sort es una función (no el resultado de una función). Pasar funciones o procedimientos como parámetros se usa desde el pascal estándar.
Necesitaría ver el código exacto que estás usando para ver porqué el compilador te marca ese error. // Saludos |
#5
|
|||
|
|||
Entiendo roman, es clara tu explicación y mala mi interpretación previa.
Haber si con parte del código se logra detectar el error. En una unidad (UPersona) declaro un objeto persona de la siguiente forma: Código:
TPersona = class private documento: Integer; nombre: String; public (* Constructores *) Constructor Create(doc: Integer; nom: String); (* Selectoras *) Function GetDocumento: Integer; Function GetNombre: String; (* Modificadoras *) Procedure SetDocumento(doc: Integer); Procedure SetNombre(nom: String); end; implementation ... end. Primero declaro las variables Código:
var Form1: TForm1; p: TPersona; listaPersonas: TObjectList; Código:
procedure TForm1.Button1Click(Sender: TObject); begin p:=TPersona.Create(StrToInt(Edit1.Text),Edit2.Text); listaPersonas:=TObjectList.Create(True); // Agregamos el objeto persona a la lista listaPersonas.Add(p); Edit1.Text:=''; Edit2.Text:=''; end; Ahora el segundo botón: Código:
procedure TForm1.Button2Click(Sender: TObject); function OrdenarPorDocumento(a: Pointer;b: Pointer): Integer; begin if TPersona(a).GetDocumento > TPersona(b).GetDocumento then result:=-1 else if TPersona(a).GetDocumento < TPersona(b).GetDocumento then result:=1 else result:=0; end; begin ListaPersonas.Sort(OrdenarPorDocumento); end; Desde ya muy agredecido por cualquier comentario. Saludos. |
#6
|
||||
|
||||
Así, a bote pronto, lo único que se me ocurre es que declares la función OrdenarPorDocumento fuera del evento Button2Click. Es posible que los procedimientos locales no se puedan pasar como parámetros. Nunca lo he intentado.
// Saludos |
#7
|
|||
|
|||
Gracias roman por tu orientación.
Veré si puedo solucionar el problema. Saludos. |
#8
|
||||
|
||||
Desempolvando los algoritmos de inserción binaria, podemos hacer una rutina que inserte los objetos en orden:
Por ejemplo, puedes definir la función comparadora:
al momento de insertar:
// Saludos |
#9
|
|||
|
|||
Excelente roman. Personalmente yo usaba búsqueda e inserción binaria en Pascal estándar con arreglos (listas estáticas), pero no con listas dinámicas (listas enlazadas). El hecho de tener en TObjectList un campo que indiza cada nodo facilita mucho las cosas.
Por otro lado, el inconveniente que tenia con la función comparadora lo solucioné con el llamado Código:
Lista.Sort(@ComparaClientes); Código:
Lista.Sort(ComparaClientes); Saludos. |
#10
|
||||
|
||||
Otra opción que a veces utilizo yo y que resulta más rápida de implementar, aunque es posible que no tan eficiente, cuando se requiere algo similar a lo que planteas (objetos + campo de ordenación) es utilizar un TStringList.
Utilizo el campo como String (para definir la ordenación) y los objetos se almacenan en la propiedad Objects. Sólo se puede utilizar si la conversión del campo se puede hacer a un string y la ordenación de este tipo es la correcta para el resultado esperado.
__________________
Germán Estévez => Web/Blog Guía de estilo, Guía alternativa Utiliza TAG's en tus mensajes. Contactar con el Clubdelphi P.D: Más tiempo dedicado a la pregunta=Mejores respuestas. |
#11
|
||||
|
||||
Hola.
Hice unas pruebas y si la función pasada como argumento está fuera del procedimiento/función (que es como la he usado anteriormente) se la puede llamar:
Ahora, enviando como argumento la dirección de la función como menciona sebamawa, y figura en el ejemplo de la ayuda de Delphi: la llamada trabaja tanto si la función es anidada como si es externa. También es muy interesante tu enfoque Neftali Saludos.
__________________
Daniel Didriksen Guía de estilo - Uso de las etiquetas - La otra guía de estilo .... |
#12
|
||||
|
||||
Cita:
// Saludos |
#13
|
||||
|
||||
Cita:
En otro tenor de cosas, no sé si el compañero sebamawa ha considerado el uso de una bse de datos. A veces se enreda uno implementando estructuras de datos para guardar información que perfectamente podría manejarse con una base. // Saludos |
#14
|
|||
|
|||
Estimados amigos, agradezco de sobremanera la ayuda y las sugerencias proporcionadas por parte de ustedes.
Respecto a Cita:
Ya que estoy en este tema, me podrán recomendar un buen manual de Delphi donde pueda estudiar. Si estuviera su versión digital para descarga sería fantástico. Gracias y saludos. |
#15
|
||||
|
||||
Cita:
// Saludos |
#16
|
||||
|
||||
¡Ah! También está el mismo libro pero para la versión 6. Tiene su título en inglés (The Dark Side of Delphi) pero el libro está en español.
// Saludos |
#17
|
||||
|
||||
Roman tengo una duda sobre tu propuesta, que dicho sea de paso, es altamente ingeniosa como acostumbras.
La inserción binaria, al menos lo que yo tengo entendido y recuerdo de cátedra (de hace ya años...) sólo tiene sentido si la lista ya está está ordenada. Es decir que para poder insertar de forma ordenada, se debe ejecutar el método Sort() previamente. No si es que he analizado mal el algoritmo que propones, pero creo ese InsertaOrdenado() falla cuando se intenta insertar el 1er item y el vez de colocarlo en el índice 0, va a parar en el índice 1. Como nota: No sería de extrañar que en las nuevas versiones de Delphi el algoritmo de ordenamiento "base" o "kernel" de TList deje de ser QuickSort. Existe un algoritmo, relativamente reciente, que es más rápido y además permite hacer inserciones de forma directa. Se llama TimSort. Java, Python ya lo tienen implementado como el algoritmo de ordenamiento por defecto en sus últimas versiones. Por otro lado nada impide hacer un TOrderObjectList que implemente justamente tanto ordenamiento como inserción ordenada. Saludos, |
#18
|
||||
|
||||
Cita:
Cita:
Cita:
Cita:
// Saludos |
#19
|
||||
|
||||
Cita:
Cita:
Cita:
Con TimSort, de lo poco que le entendí de su funcionamiento, es capaz de determinar cuando aplicar un Merge() y cuando aprovechar una insercción. Si se tuviera TimSort por defecto, al hacer un Add, Insert, Move, etc de forma "automática" se hacen las cosas con un único algoritmo y es posible que en ningún momento se ejecute la parte del Merge(). Cita:
Saludos, |
#20
|
||||
|
||||
Cita:
Bueno, es que esto sería imposible // Saludos |
Herramientas | Buscar en Tema |
Desplegado | |
|
|
Temas Similares | ||||
Tema | Autor | Foro | Respuestas | Último mensaje |
adotable ordenado por un campo | leorene | Conexión con bases de datos | 2 | 13-02-2007 01:00:16 |
Select ordenado por un campo pero localizado por otro | ingel | SQL | 2 | 04-01-2006 17:33:23 |
Imprimir el listado ordenado por un campo | ilichhernandez | Impresión | 3 | 03-11-2005 19:44:13 |
DBLookupComboBox ordenado | Supermagayin | Conexión con bases de datos | 2 | 12-04-2005 00:18:33 |
Grid ordenado al añadir registro | Tomás | Varios | 0 | 13-03-2004 14:58:02 |
|