DMarlon Studio

Lección 11 · 11 de 20

Genéricos con fgl · Pascal

Use las listas y mapas genéricos de la unidad fgl de Free Pascal, TFPGList y TFPGMap, para guardar pedidos y existencias con su tipo exacto.

Pascal · Genéricos con fgl en DMarlon Studio: el código del ejemplo y su salida en la terminal

Un genérico es un tipo con un hueco para otro tipo. La unidad `fgl` de Free Pascal trae TFPGList<T> (una lista) y TFPGMap<K, V> (un mapa de clave y valor). En modo objfpc se concretan con `specialize`: TQtyList es una lista de Integer y TStockMap, un mapa de String a Integer. El compilador comprueba los tipos: en orders no cabe un texto.

orders.Sort(@Descending) ordena con su propia función de comparación, que devuelve un número negativo, cero o positivo según el orden de a y b. Con b - a, de mayor a menor. Después, orders[0] es el pedido más grande y orders.Last, el más pequeño.

Con `stock.Sorted := True`, el mapa mantiene las claves en orden alfabético y las busca por búsqueda binaria. Su propiedad por defecto permite escribir stock['monitor'] := 7: si la clave no existe, la añade; si existe, cambia su valor, como hace la línea que descuenta 5 teclados.

Para recorrerlo, Keys[i] y Data[i] dan la clave y el valor de cada posición, ya ordenados. Leer stock['webcam'] lanzaría una excepción porque no existe; para preguntar sin riesgo está `IndexOf`, que devuelve -1. Las dos colecciones son objetos, así que se liberan en el finally.

Código · main.pas

program main;uses fgl;type  TQtyList = specialize TFPGList<Integer>;  TStockMap = specialize TFPGMap<String, Integer>;function Descending(const a, b: Integer): Integer;begin  Result := b - a;end;var  orders: TQtyList;  stock: TStockMap;  i: Integer;begin  orders := TQtyList.Create;  stock := TStockMap.Create;  try    orders.Add(12); orders.Add(5); orders.Add(30); orders.Add(8);    orders.Sort(@Descending);    WriteLn('Orders: ', orders.Count, ', largest: ', orders[0], ', smallest: ', orders.Last);    stock.Sorted := True;  // keys kept in order, found by binary search    stock['monitor'] := 7;    stock['keyboard'] := 25;    stock['mouse'] := 40;    stock['keyboard'] := stock['keyboard'] - 5;  // 5 keyboards sold    for i := 0 to stock.Count - 1 do      WriteLn(stock.Keys[i]:10, stock.Data[i]:4);    WriteLn('Has webcams: ', stock.IndexOf('webcam') >= 0);  finally    orders.Free;    stock.Free;  end;end.

Salida · fpc main.pas && ./main

Orders: 4, largest: 30, smallest: 5
  keyboard  20
   monitor   7
     mouse  40
Has webcams: FALSE

Para recordar

  • specialize TFPGList<Integer> crea una lista de enteros con su tipo comprobado.
  • Sort recibe una función que compara dos elementos.
  • TFPGMap con Sorted := True guarda las claves en orden.
  • mapa[clave] := valor añade o actualiza.
  • IndexOf comprueba si una clave existe sin lanzar errores.

Ejercicio

Añada al mapa 'webcam' con 12 unidades solo si IndexOf dice que no existe, y escriba cuántas unidades hay en total sumando Data[i].