Lección 12 · 12 de 20
Generics.Collections · Pascal
Cuente ventas por ciudad con TDictionary y ordene el resultado con TList, las colecciones genéricas de Generics.Collections en Free Pascal.

La unidad `Generics.Collections` ofrece las mismas colecciones que Delphi: TList<T>, TDictionary<K, V>, TObjectList<T>, TQueue<T>… Aquí TSales es un diccionario de ciudad a número de pedidos y TCityList, una lista de textos.
El bucle cuenta los pedidos de Orders. `TryGetValue` busca la ciudad y, si está, deja su cuenta en count y devuelve True; entonces sales[city] := count + 1 la actualiza. Si no está, Add la crea con 1. Ojo: Add con una clave repetida lanza una excepción; para «añadir o cambiar» está AddOrSetValue.
Un diccionario guarda las claves según su *hash*, así que su orden no es fiable y podría cambiar con otra versión o con otros datos. Para una salida estable, el programa copia las claves a la lista con cities.AddRange(sales.Keys), las ordena con cities.Sort y recorre la lista, pidiendo a sales[city] cada cuenta.
Count dice cuántas ciudades hay y `ContainsKey` pregunta por una clave sin riesgo. Las dos colecciones se liberan en el finally. Al compilar, Free Pascal 3.2.2 muestra unos avisos que vienen de la propia unidad (Constructing a class ... with abstract method): son internos de la biblioteca y no afectan al programa.
Código · main.pas
program main;uses Generics.Collections;type TCityList = specialize TList<String>; TSales = specialize TDictionary<String, Integer>;const Orders: array[0..6] of String = ('Madrid', 'Sevilla', 'Madrid', 'Bilbao', 'Sevilla', 'Madrid', 'Valencia');var sales: TSales; cities: TCityList; city: String; count: Integer;begin sales := TSales.Create; cities := TCityList.Create; try for city in Orders do if sales.TryGetValue(city, count) then sales[city] := count + 1 else sales.Add(city, 1); // A dictionary has no fixed order: copy the keys and sort them cities.AddRange(sales.Keys); cities.Sort; for city in cities do WriteLn(city:9, sales[city]:3); WriteLn('Cities: ', sales.Count, ', any in Malaga: ', sales.ContainsKey('Malaga')); finally cities.Free; sales.Free; end;end.Salida · fpc main.pas && ./main
Bilbao 1 Madrid 3 Sevilla 2 Valencia 1 Cities: 4, any in Malaga: FALSE
Para recordar
TDictionary<K, V>busca valores por clave muy deprisa.TryGetValuelee sin lanzar errores si la clave no existe.Addfalla con claves repetidas;AddOrSetValue, no.- El orden de un diccionario no está garantizado: ordene las claves aparte.
TList<T>tieneAddRange,Sortyfor ... in.
Ejercicio
Cree un segundo diccionario TDictionary<String, Double> con el importe de cada pedido y escriba, ciudad por ciudad y en orden alfabético, cuánto se ha facturado.