Recent

Author Topic: Duda sobre listas.  (Read 1056 times)

BlueIcaro

  • Hero Member
  • *****
  • Posts: 576
Duda sobre listas.
« on: April 23, 2019, 09:47:49 am »
Hola a todos, tengo una duda de como plantear una lista de elemento.
Hasta ahora siempre trabajé con TCollectionItem, y TCollection.
Definía una clase TCollectionItem, algo asi:
Code: [Select]
type
  TMiItem = class(TCollectionItem)
  private 
    FNombre: string;
    FNumero: string;
  public
    property Numero: string read FNumero write FNumero;
    property Nombre: string read FNombre write FNombre;   
  end;         
Y la clase TCollection algo así:
Code: [Select]
type
  TElementos = class(TCollection)
  private
    function GetItem(Index: integer): TMiItem ; 
  public
    function Add: TMiItem ;
    property Item[Index: integer]: TMiItem read GetItem;
  end;                     
 
El problema que me encuentro ahora, necesito hacer una lista que contenga dos tipos Items.
¿Hay alguna clase que me sirva para eso?.
Gracias
/BlueIcaro
       
Remenber, the lazarus wiki is your friend: http://wiki.lazarus.freepascal.org/Main_Page
General questions (several lenguages) http://wiki.lazarus.freepascal.org/

Thaddy

  • Hero Member
  • *****
  • Posts: 8503
Re: Duda sobre listas.
« Reply #1 on: April 23, 2019, 09:59:54 am »
fcl:
TFPGMapObject
generics.collections:
TObjectDictionary.

But there are many options, depending on what you want.
Last week I posted some very simple examples on this forum.
Read the manuals and if you are a professional get a proper education in computer science. Makes the forum a lot cleaner.

Edson

  • Hero Member
  • *****
  • Posts: 1029
Re: Duda sobre listas.
« Reply #2 on: April 23, 2019, 06:06:00 pm »
El problema que me encuentro ahora, necesito hacer una lista que contenga dos tipos Items.
¿Hay alguna clase que me sirva para eso?.
¿Te refieres a:?
1. 2 tipos de ítems en un solo ítem.
2. Ítems de 2 tipos diferentes.

Para el caso 1, no veo complicación, solo que ahora tu TMiItem deberá incluir dos campos de tipo Ítem.
Aunque yo lo haría con listas genéricas, crrando una clase que contenga los campos/objetos que quiera.
para el caso 2, podrías hacer uso del polimorfismo y crear una clase base y dos clases derivadas.
Lazarus 1.6 - FPC 3.0.0 - x86_64-win64 on  Windows 7

BlueIcaro

  • Hero Member
  • *****
  • Posts: 576
Re: Duda sobre listas.
« Reply #3 on: April 26, 2019, 12:02:48 pm »
El problema que me encuentro ahora, necesito hacer una lista que contenga dos tipos Items.
¿Hay alguna clase que me sirva para eso?.
¿Te refieres a:?
1. 2 tipos de ítems en un solo ítem.
2. Ítems de 2 tipos diferentes.

Para el caso 1, no veo complicación, solo que ahora tu TMiItem deberá incluir dos campos de tipo Ítem.
Aunque yo lo haría con listas genéricas, crrando una clase que contenga los campos/objetos que quiera.
para el caso 2, podrías hacer uso del polimorfismo y crear una clase base y dos clases derivadas.
Hola, lo que quiero hacer es una lista, tengas items, pero no de una clase determinada, sino de dos.
Por ejemplo. Crear una lista que contenga de un centro de estudio o escuela. Así tendría una lista con dos tipos de item. Uno sería del tipo Alumno, y otro sería otro diferente, que sería sería del tipo Profesor.
Creo que la opción de generics es buena. Estoy mirando ejemplos.
Saludos
Remenber, the lazarus wiki is your friend: http://wiki.lazarus.freepascal.org/Main_Page
General questions (several lenguages) http://wiki.lazarus.freepascal.org/

lucamar

  • Hero Member
  • *****
  • Posts: 1959
Re: Duda sobre listas.
« Reply #4 on: April 26, 2019, 03:53:57 pm »
Hola, lo que quiero hacer es una lista, tengas items, pero no de una clase determinada, sino de dos.
Por ejemplo. Crear una lista que contenga de un centro de estudio o escuela. Así tendría una lista con dos tipos de item. Uno sería del tipo Alumno, y otro sería otro diferente, que sería sería del tipo Profesor.
Creo que la opción de generics es buena. Estoy mirando ejemplos.
Saludos

Aún usando genéricos estás en el mismo problema. Lo mejor es tomar la segunda opción que te dio Edson: Crea un clase base, de la que serán los items a añadir a la lista, y deriva de ella una clase "alumnos" y otra "profesores".

Cuando necesites diferenciar es fácil hacer:
Code: [Select]
if Lista.Item[i] is TClaseAlumno then ...o, para profesores,
Code: [Select]
if EsteItem is TClaseProfesor then ...
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 2.0.2/2.0.4  - FPC 3.0.4 on:
(K|L)Ubuntu 12..16, Windows XP SP3, various DOSes.

garlar27

  • Hero Member
  • *****
  • Posts: 597
Re: Duda sobre listas.
« Reply #5 on: April 26, 2019, 05:15:18 pm »
Este es un caso típico de Entidades y Roles.

Y en tu aplicación podrías implementarlo de esta forma:

Code: Pascal  [Select]
  1.   TEntidad = class(TCollectionItem)
  2.   end;
  3.  
  4.   TProfesor = class(TEntidad)
  5.   end;
  6.  
  7.   TAlumno = class(TEntidad)
  8.   end;
  9.  

o esta otra opción:
Code: Pascal  [Select]
  1.   TEntidad = class(TObject)
  2.   end;
  3.  
  4.   TProfesor = class(TEntidad)
  5.   end;
  6.  
  7.   TAlumno = class(TEntidad)
  8.   end;
  9.  
  10.   TEntidadItem = (TCollectionItem)
  11.   private
  12.     FEntidad: TEntidad;
  13.   public
  14.     destructor Destroy; override; // aquí debes liberar FEntidad
  15.     function Add(unaEntidad: TEntidad): TEntidadItem;
  16.     property Entidad: TEntidad read FEntidad;
  17.   end;
  18.  

Personalmente, yo usaría el segundo ejemplo.


Por las dudas,

Seguro hay miles de libros y ejemplos en la web explicando esto desde el punto de vista del diseño y la programación.
Tienes una tabla "ENTIDAD" (con datos comunes a todas las entidades) y una colección de tablas que indican los roles que puede asumir una entidad (por ejemplo: ALUMNO, PROFESOR, CELADOR, PROVEEDOR, Y_CUALQUIER_OTRO_ROL_QUE_SE_NECESITE).


lucamar

  • Hero Member
  • *****
  • Posts: 1959
Re: Duda sobre listas.
« Reply #6 on: April 26, 2019, 05:59:04 pm »
Ahondando un poco más, incluso podrías hacer algo así como:
Code: Pascal  [Select]
  1.   TEntidad = class(TCollectionItem)
  2.   public
  3.     function EsProfesor: Boolean; virtual; abstract;
  4.     function EsAlumno: Boolean; virtual; abstract;
  5.   end;
  6.  
  7.   TProfesor = class(TEntidad)
  8.   public
  9.     function EsProfesor: Boolean; override; { Result := True }
  10.     function EsAlumno: Boolean; override; { Result := False }
  11.   end;
  12.  
  13.   TAlumno = class(TEntidad)
  14.   public
  15.     function EsProfesor: Boolean; override; { Result := False }
  16.     function EsAlumno: Boolean; override; { Result := True }
  17.   end;

Eso permite saber inmediatamente qué tipo the item estás leyendo de la colección.

Podía hacerse de un modo más robusto (por ejemplo usando un método "GetRole" que devuelva la clase o un miembro de una enumeración) pero la idea básica es esa.
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 2.0.2/2.0.4  - FPC 3.0.4 on:
(K|L)Ubuntu 12..16, Windows XP SP3, various DOSes.

garlar27

  • Hero Member
  • *****
  • Posts: 597
Re: Duda sobre listas.
« Reply #7 on: April 26, 2019, 06:35:44 pm »
Podía hacerse de un modo más robusto (por ejemplo usando un método "GetRole" que devuelva la clase o un miembro de una enumeración) pero la idea básica es esa.

Una entidad puede tener varios roles asignados. Por ejemplo un PROFESOR de informática podría ser ALUMNO de un curso de arte que se dicta en la academia, y además ser un PROVEEDOR de servicio técnico.
Por lo que sugiero que en lugar de "GetRole" sea "HasRole(ARole: TRole): Boolean;" o "GetRoles(): Set of TRole;"

BlueIcaro

  • Hero Member
  • *****
  • Posts: 576
Re: Duda sobre listas.
« Reply #8 on: May 01, 2019, 11:25:46 am »
Gracias a todos por las respuestas. 
El ejemplo que puse, era algo genérico. Realmente lo que necesito es leer un archivo de texto, dentro del cual hay definición de dos tipos de elementos, que son parecidos pero no iguales.
Y no se da la circunstancia de que uno pueda tener el rol de otro.
Es información sobre una máquina de mi trabajo.
Un tipo de entradas es de esta forma:
Quote
P[1:"COGIDA"]{
   GP1:
   UF : 1, UT : 2,   
   J1=   -81.857 deg,   J2=    47.883 deg,   J3=   -49.767 deg,
   J4=    -6.301 deg,   J5=   -89.018 deg,   J6=    -5.289 deg
};
Y el otro tipo es así:
Quote
P[2]{
   GP1:
   UF : 1, UT : 2,      CONFIG : 'N U T, 0, 0, 0',
   X =  2817.633  mm,   Y =  1893.810  mm,   Z =  2118.963  mm,
   W =  -169.750 deg,   P =    14.966 deg,   R =   -18.503 deg

Los únicos datos comunes son "UF" y "UT" así que haré una clase común que contenga esa información y luego haré las dos clases descendientes con los datos específicos de cada uno, siguiendo el ejemplo de Lucamar.

/BlueIcaro
 
« Last Edit: May 01, 2019, 11:38:14 am by BlueIcaro »
Remenber, the lazarus wiki is your friend: http://wiki.lazarus.freepascal.org/Main_Page
General questions (several lenguages) http://wiki.lazarus.freepascal.org/