Arrays in Ninox

Einfache Arrays

Der Umgang mit Text- oder Zahlen-Arrays ist unkompliziert:

var myArray := ["a", "b", "d"];

index(myArray, "b");
myArray := array(myArray, ["c"]);

myArray order this;

Sortieren lässt sich auch mit order, sort und unsort – für Text- wie für Zahlen-Arrays.
Weitere Funktionen rund um Arrays finden Sie in der Ninox-Dokumentation.

Zweidimensionale Arrays

Ninox unterstützt zweidimensionale Arrays nicht unmittelbar. Verwenden Sie stattdessen ein Array aus JSON-Objekten.
Hier zum Beispiel die Sortierung des Arrays nach dem zweiten Element des Feldes d2:

var myArray := [{'d2':["a", "Z"]}, {'d2':["b", "B"]}, {'d2':["c", "C"]}, {'d2':["d", "D"]}];

(myArray order by item('d2', 1));

Dieser Code liefert: [{"d2":["b","B"]},{"d2":["c","C"]},{"d2":["d","D"]},{"d2":["a","Z"]}]

Arrays filtern

Arrays lassen sich genauso filtern wie das Ergebnis eines select. Bei Text- oder Zahlen-Arrays verweisen Sie mit this auf den gefilterten Wert:

var myArray := ["Jan", "Fred", "Jacques"];
myArray[this like "J"] order this;

Bei JSON-Arrays verwenden Sie direkt den Schlüssel:

var myArray := [
  { 'prénom' : "Jan", nom : "Augustin" },
  { 'prénom' : "Fred", nom : "Baillot" },
  { 'prénom' : "Jacques", nom : "Tur" }
];

myArray[nom like "i"] order 'prénom';

Dieser Code liefert ein Array aus JSON: [{"prénom":"Fred","nom":"Baillot"}, {"prénom":"Jan","nom":"Augustin"}]

Eigene Operationen auf JSON-Arrays

Bei JSON-Arrays können Sie einen Codeblock (in Klammern) einfügen, der bei jedem Durchlauf eigene Operationen ausführt. Wie bei for in richtet sich der Typ des Ergebnis-Arrays nach der letzten Zeile des Blocks.

Beispiel: Berechnung der Länge der vollständigen Namen (prénom + nom):

var myArray := [
  { 'prénom' : "Leo", nom : "Martin" },
  { 'prénom' : "Paul", nom : "Garnet" },
  { 'prénom' : "Pierre", nom : "Dur" }
];

var nameLengths := myArray[nom like "a"].(
    var fullName := ---{'prénom'} {nom}---;
    length(fullName)
);
nameLengths;

Dieser Code liefert ein Array aus Zahlen [10, 11] – die Längen der vollständigen Namen.

Ein leeres, typisiertes Array anlegen

In Ninox besteht der übliche Kniff, ein leeres Array mit dem richtigen Datensatztyp zu erzeugen, darin, ein mit where false gefiltertes select auszuführen.
Die Abfrage liefert null Datensätze, bewahrt aber den Typ der Array-Elemente.

"Empty Invoice Item array:";
let t := (select 'Invoice Item' where false);
  • t ist nun ein Array, dessen Elemente vom Typ Invoice Item sind.
  • Da es leer und zugleich typisiert ist, lässt es sich gefahrlos als Ausgangspunkt für array()-Operationen weiterverwenden.

Warum nicht einfach []?

Das Literal [] ist ein untypisiertes Array. Oft geht das gut, doch in Verbindung mit array() auf Datensatzsammlungen kann Ninox Typunstimmigkeiten bemängeln.
Das Muster select … where false umgeht dieses Problem vollständig.

Ein leeres Array für einfache Typen anlegen (Zahl, Text, JSON …)

Wenn Sie ein leeres Array für skalare Werte brauchen – Zahlen, Zeichenfolgen oder JSON-Objekte –, gibt es keine zugrunde liegende Tabelle, aus der sich ein select ableiten ließe.
Ein typisiertes leeres Array erhalten Sie dennoch, indem Sie [] mit einem Platzhalterelement füllen und dieses sofort wieder herausfiltern:

"Empty number / text / JSON array:";
let t := [1][false];   "t is now an empty but number typed array";

[1] erzeugt ein einelementiges Zahlen-Array; der Filter [false] entfernt dieses Element und lässt ein leeres Array zurück, das den Typ number behält.
Verwenden Sie statt 1 ein Text- oder JSON-Literal, wenn Sie diese Typen benötigen.

Ein zweidimensionales Array flach machen

Jede Invoice enthält ihr eigenes Unter-Array Invoice Items. Um eine einzige Liste mit allen Positionen sämtlicher Rechnungen zu erhalten, durchlaufen Sie die Rechnungen und hängen deren Unter-Arrays aneinander.

"Initialize empty array:";
let t := (select 'Invoice Item' where false);

"Iterate over each invoice and add its items:";
for i in Invoices do
    t := array(t, i.'Invoice Items')
end;

"Return the flattened list:";
t

So funktioniert es

  1. for i in Invoices do … end durchläuft jeden Datensatz vom Typ Invoice.
  2. array(t, i.'Invoice Items') verkettet den aktuellen Wert von t mit dem Array der Positionen dieser Rechnung.
    • Im ersten Durchlauf werden die Positionen der ersten Rechnung angehängt.
    • Im zweiten Durchlauf kommen die Positionen der zweiten Rechnung hinzu, und so fort.
  3. Nach dem Ende der Schleife enthält t alle Positionen aller Rechnungen in einem einzigen, flachen Array.

Nun können Sie Operationen wie count(t) ausführen, um die Gesamtzahl der Positionen zu ermitteln, oder t unmittelbar durchlaufen und filtern.