Tableaux
Les tableaux constituent une liste d'éléments indexés.
Il existe 4 types de tableaux :
- les tableaux statiques, dont la taille est fixe
- les tableaux dynamiques, dont la taille est variable
- les tableaux dit "ouverts", destinés au passage de paramètres
- les tableaux associatifs, dont l'index est d'un type quelconque
Les éléments d'un tableau sont spécifiés et plaçant l'index entre crochets :
i := table[2]; // place l'élément d'indice 2 de 'table' dans i
La borne basse des indices peut être récupérée par Low(), la borne haute par High() et le nombre d'élément par Length() (ou Count()).
Pour les tableaux multi-dimensionnels, les indices sont séparés par des virgules ','.
Tableaux statiques
Les tableaux statiques sont des types valeur, une affectation copie les données.
for var i := 1 to 10 do
table[i] := i;
// strictement équivalent à
for var i := table.Low to table.High do
table[i] := i;
Un tableau statique dont l'index est un énuméra peut être dimensionné directement avec la syntaxe
// les deux déclarations ci-dessous sont équivalentes
var table1 : array [TMyEnum.Low .. TMyEnum.High] of Integer;
var table2 : array [TMyEnum] of Integer;
var table2 : array [alpha .. gamma] of Integer; // non-équivalente si TMyEnum est étendu
Tableaux dynamiques
array of type
Les tableaux dynamiques sont un type référence, ils sont déclarés sans étendues, leur borne basse est toujours zéro. Ils peuvent être utilisés comme structure de pile.
var i : Integer;
table := new Integer[10];
for i:=0 to table.High do
table[i] := i;
On peut utiliser les opérateurs in et not in pour tester la présence d'un élément.
Ils supportent de plus les pseudo-méthodes suivantes :
- Add(item) / Push(item) : ajoute un élément à la fin du tableau. Ces méthodes acceptent en paramètre des tableaux dynamiques, et un nombre variable de paramètres, ce qui permet d'ajouter plusieurs éléments avec un seul appel.
- Clear() : vide le tableau (équivalent à SetLength(0)).
- Contains(item) : retourne si un élément est contenu, alternative équivalente à in (Qubes 9.0).
- Copy(startIndex[, count]) : crée un nouveau tableau dynamique contenant count éléments pris depuis startIndex, si count n'est pas spécifié, copie jusqu'à la fin du tableau.
- Delete(index[, count]) : supprime count élément(s) à l'index spécifié, si count n'est pas spécifié, supprime un seul élément.
- Filter(filterFunction) : constitue un nouveau tableau comprenant tous les éléments pour lesquels filterFunction a retourné True (Qubes 9.0).
- ForEach(forEachFunction) : applique une fonction à tous les éléments (Qubes 10.0), cette méthode est plutôt destinée au contexte de transpilation vers JavaScript.
- IndexOf(item[, startIndex]) : recherche l'index d'un élément, retourne une valeur négative si non trouvé.
- Insert(index, item) : insère un élément à l'index spécifié.
- Map(mapFunction) : passe chaque élément du tableau à mapFonction et constitue un nouveau tableau avec les résultats.
- Move(fromIndex, toIndex) : déplace un élément d'un index vers un autre (Qubes 7.2).
- Peek() : retourne le dernier élément du tableau.
- Pop() : retourne le dernier élément et le supprime du tableau.
- Remove(item[, startIndex]) : supprime la première occurrence de l'élément indiqué s'il existe à partir d'un index et retourne son index, retourne une valeur négative si non trouvé (Qubes 6.1).
- Reverse() : inverse l'ordre des éléments.
- SetLength(newLength) : ajuste la longueur du tableau.
- Sort([compare function]) : effectue un tri du tableau. La fonction de comparaison doit accepter deux éléments et retourner un entier indiquant le résultat de la comparaison. La fonction de comparaison est optionnelle pour les tableaux d'entier, de flottants et de chaîne (tri non sensible à la casse par défaut).
- Swap(index1, index2) : échange les éléments d'index spécifiés.
array of String
Les tableaux de chaînes possèdent les pseudo-méthodes complémentaires suivantes :
- Join(delimiter) : renvoie une chaîne constituée par toutes les chaînes du tableau séparées par le délimiteur indiqué.
function CompareAfterSpace(a, b : String) : Integer;
begin
Result := a.After(' ').CompareText(b.After(' '));
end;
var s : array of String;
s.Add('hello world', 'bye bye');
s.Sort(CompareAfterSpace);
PrintLn(s.Join(','));
array of Float
Les tableaux de flottants à partir de Qubes 9.0 possèdent les pseudo-méthodes complémentaires suivantes :
- Multiply(facteur) : multiplie tous les éléments du tableau par le facteur et renvoi le tableau.
- MultiplyAdd(facteur, offset) : multiplie tous les éléments du tableau par le facteur, ajoute l'offset, puis renvoi le tableau (Qubes 10.0).
- Offset(delta) : ajoute delta à tous les éléments du tableau et renvoi le tableau.
- Reciprocal : applique la réciproque (1/x) à tous les éléments du tableau et renvoi le tableau.
Tableaux ouverts
Ils sont à déclarer en tant que paramètres comme 'array of const'.
Limites
Les tableaux statiques résident sur la pile, au sein d'un record ou d'une classe, leur taille limite sera de l'ordre de quelques dizaine à quelques centaines de milliers d'éléments. En pratique il est préférable de les réserver à de petits tableaux pour des considérations de performance.
Les tableaux dynamiques sont alloués dynamiquement, et limités par la mémoire disponible.
A compter de la 9.2021.0308 ils supportent plus de 2147483648 éléments, limite dépassable uniquement dans un contexte 64bits, un tableau de cette taille occupera par exemple:
- éléments Float ou Integer, 8 octets / élément, soit 16 Go de mémoire
- éléments Boolean, 1 bit / élément, soit 256 Mo de mémoire
Préalablement à la 9.2021.0308, l'encombrement par élément est 16 octets en 32 bits, et 24 octets en 64 bits.