0

filter und order eigener Arrays

Wenn man Arrays manuell, also nicht über select() erstellt, kann man leider where zum filtern nicht benutzen. Auch order funktioniert nur mit geänderter Syntax. Ich habe mal eine Beispielliste erstellt, die einige for-Schleifen erspart insbesondere, wenn Arrays verglichen werden. Wer in seinem Code noch Zeilen einsparen möchte, kann vielleicht von den Anregungen profitieren. Fehler gefunden? Posten. Mirko

let one := ["Peter", "Paul", "Mary", "tim", "Tim", "paul"];
let two := ["Mary", "Suzi"];
let three := [1, 21, 3, 4, 5, 7, 11, 9];
"Datumrange die letzten 1200 Tage, step: zwei Tage";
let four := range(today() - 1200, today(), 2 * 86400000);
---
FILTER
---;
---
################################# stringarray ####################################
---;
"Ist two ein vollständiges subarray von one?";
cnt(one[contains(two, this)]) = cnt(two);
"Filtere alle Elemente aus two, die auch in one enthalten sind!";
two[contains(one, this)];
"Filtere alle Elemente aus two, die NICHT in one enthalten sind!";
two[not contains(one, this)];
"Filtere alle Elemente mit geradem Index ≙ jedem zweiten Element des Stringarray!";
one[even(index(one, this))];
"Filtere alle Elemente, die kürzer als das letzte Element des Stringarrays sind!";
one[length(this) < length(last(one))];
"Filtere alle Elemente die ein T oder t enthalten! case-insensitiv";
one[this like "t"];
"oder einfach nur";
one[like "t"];
"Filtere alle Elemente die den Großbuchstaben T enthalten! case-sensitiv";
one[contains(this, "T")];
"Aus zwei Arrays alle einmaligen Werte (Unikate) zusammenführen ";
array(one, two[not contains(one, this)]);
"oder - eleganter";
unique(one, two);
---
################################# numberarray ####################################
---;
"Filtere alle Elemente die ungerade sind!";
three[odd(this)];
"Filtere alle Elemente die ohne Rest durch 3 teilbar sind aus einem Zahlenarray!";
three[this % 3 = 0];
"Filtere alle Elemente die eine 1 enthalten aus einem Zahlenarray!";
three[text(this) like "1"];
"Filtere alle Elemente die kleiner sind als der Durchschnitt aus einem Zahlenarray!";
three[this < avg(three)];
"oder einfach nur";
three[< avg(three)];
"Filtere die drei größten Elemente aus einem Zahlenarray!";
slice(sort(three), -3, null);
"oder auch";
slice(rsort(three), 0, 3);
"Halbiere das Array (natürlich nur wenn es geradzahlig ist)!";
"erste Hälfte";
slice(three, 0, cnt(three) / 2);
"zweite Hälfte";
slice(three, cnt(three) / 2, null);
"Filtere durch Entfernung des/der größte(n) und kleinste(n) Element(e) aus einem Zahlenarray!";
three[this != max(three) and this != min(three)];
"oder einfach nur";
three[!= max(three) and != min(three)];
---
################################# datearray ####################################
---;
"Filtere alle Montage aus einem Datumarray!";
four[weekday(date(this)) = 0];
"Filtere alle Arbeitstage aus einem Datumarray!";
four[weekday(date(this)) < 5];
"Filtere den letzten Sonntag im Datumarray!";
last(four[weekday(date(this)) = 6]);
"Filtere alle Tage November 2024";
four[year(this) = 2024 and month(this) = 11];
"Filtere alle Tage der ersten Kalenderwoche im Datumarray!";
four[week(this) = week(first(four))];
"Filtere alle Daten mit Alter größer 2!";
four[age(this) > 2];
---
SORT-ORDER
---;
"Sortierung nach Länge der Namen!";
let s1 := (one order by length(this));
"Sortierung nach letztem Buchstaben!";
let s2 := (one order by substr(this, -1));
"Sortiere alphabetisch - ALLE Wörter die mit Kleinbuchstaben beginnen, weden nach denen mit Großbuchstaben sortiert!";
let s3 := (one order by this);
"Sortiere alphabetisch - gleichlautende Wörter die mit Kleinbuchstaben beginnen, werden vor denen mit Großbuchstaben sortiert!";
let s4 := sort(one);

4 Antworten

null
    • Ninox Widgets & User Interfaces
    • Jakob_Jordan
    • vor 13 Tagen
    • Gemeldet - anzeigen

    probier mal den array als variable noch mal in eine for schleife zu setzen
    let filterArray:= for item in one do item end;
    filterArray[item="Peter"]

    oder mit object arrays würde es auch gehen
    let one:= [{name: "Peter", age:"old"}, {name: "Peter", age:"young"}, {name:"Paul", age:"young"}]
    let filterArray:= for item in one do item end;
    filterArray[name="Peter" and age="old"]

    ich nehme eigentlich immer lieber object arrays, da hast du im Nachgang mehr potential anzupassen

    hoffe ich hab keinen syntax fehler drin, ansonsten teste ich noch mal

      • mirko3
      • vor 13 Tagen
      • Gemeldet - anzeigen

       Hi. Dein erstes Script funktioniert so nicht. Item ist da kein Schlüsselwort - du weißt schon, andere Umgebung. In Arrays (den selbst erstellten) geht es mit this. Und tatsächlich ist es nicht nötig eine Schleife dazwischen zu schalten. Es reicht:

      let one:= [{name: "Peter", age:"old"}, {name: "Pit", age:"young"}, {name:"Paul", age:"middle"}]
      one[name="Peter"]
      

      unnötig, aber gedacht, steht auch hier this quasi wie ein Iterator voran.

      let one:= [{name: "Peter", age:"old"}, {name: "Pit", age:"young"}, {name:"Paul", age:"middle"}]
      one[this.name="Peter"]
      

      Ich bin kein Schleifengegner, hab nur experimentiert, wie man sie vermeiden kann. Codealternative. 

      Gruß Mirko

      • Maurice
      • vor 11 Tagen
      • Gemeldet - anzeigen

       vielleicht kannst du nochmal die Bedeutung des "this" klar machen. Ich finde die Lösungen von dir, Mirko, (wie immer) sehr interessant und wäre nie auf die Verwendung von this in diesem Kontext gekommen, da ich immer dachte, dass this (nur) der aktuelle Datensatz ist.

      Am Beispiel

      cnt(one[contains(two, this)]) = cnt(two);
      

      verstehe ich das so, dass das this durch das erste array durch iteriert (das meinst du, wenn ich dich im Post richtig verstanden haben). Das this iteriert durch das array, in dessen Bedingung es steht.

      Die Frage, die bleint: was geschieht dann Ninox-intern: wird dann eine Schleife "gefahren" oder gibt es einen effizienteren Algorithmus. Letzteres würde bedeuten, dass ich meine Scripts mal auf aufwändige Schleifen prüfen könnte (bevor contains([nr],nr) in Vers. 3.8 zur Verfügung stand, habe ich auch Schleifen scripten müssen für bestimmte Abfragen, insbesondere bei dmulti-Feldern).

      Maurice

      • mirko3
      • vor 10 Tagen
      • Gemeldet - anzeigen

       Eine zufällige Entdeckung bei Jacques Tur im englischen Forum führte mich zu this in Arrays. Ich habe dann nur weiter experimentiert. In vielen Programmiersprachen gibt es höhere Funktionen (map, reduce, filter, sort), die ein Array entgegennehmen und eine Funktion, meist ein Closure. Mit denen können dann elegant Arraymanipulationen durchgeführt werden ohne Schleifen. Dabei funktionieren diese Closure mit einem Iterator. Meist werden dafür Platzhalter benutzt ($0 etc.). Ich denke, dass in NINOX-Script "this" auch ein Platzhalter ist. Manchmal steht es für einen Record, in Fällen einfacher Arrays ist es das Element des Arrays. In select() kann man es einfach weglassen, obwohl es auch dort stehen könnte. Z.B. 

      select Tabelle where this.Name = "Mirko"

      NINOX-Script akzeptiert diese Schreibweise ebenfalls. Hier steht dann this für den Record. Und ja, ich lasse dadurch dann gern die vorher noch notwendigen Schleifen weg. Zwei Zeilen Code weniger;-) Mirko

Content aside

  • vor 10 TagenZuletzt aktiv
  • 4Antworten
  • 49Ansichten
  • 4 Folge bereits