Gunnar Bittersmann: Array.findLast in PHP

Ich habe solch ein Array

const episodes = [
	{ name: 'The Next Generation', datePublished: '2023-02-16' },
	{ name: 'Disengage', datePublished: '2023-02-23' },
	{ name: 'Seventeen Seconds' },
	{ name: 'No Win Scenario' },
	{ name: 'Imposter' },
	{ name: 'Bounty' },
];

und möchte das letzte Element finden, das eine bestimmte Eigenschaft hat:

const recent = episodes.findLast(element => element.datePublished);

console.log(recent.datePublished); // 2023-02-23

In JavaScript kein Problem. Aber wie macht man das in PHP? Gibt’s da eine entsprechende Funktion oder muss man das selbst mit einer Schleife implementieren?

🖖 Живіть довго і процвітайте

--
„Im Vergleich mit Elon Musk bei Twitter ist ein Elefant im Porzellanladen eine Ballerina.“
— @Grantscheam auf Twitter
  1. Hello,

    ist das das einzige Subelement im Array, über das Du etwas wissen willst? Also keinster, größter, ..., Eintrag, Sortierung nach Größe?

    Oder gibt es noch andere Subelemente im Array, mit denen Du etwas anstellen willst?

    Und definiere bitte "letzter Eintrag" etwas genauer. Sortierung ist bei PHP-"Arrays" ein spezielles Thema.

    Wenn Du meine Traktate zu möglichen Array-Aufbauten in PHP im Archiv suchst (Stichworte: Zeilenarray, Spaltenarray) kommt Dir vielleicht eine Idee dazu.

    Ich will das hier nicht näher vertiefen. Das würde voraussichtlich nur wieder Shitstorms hervorrufen.

    Glück Auf
    Tom vom Berg

    --
    Es gibt soviel Sonne, nutzen wir sie.
    www.Solar-Harz.de
    S☼nnige Grüße aus dem Oberharz
    1. @@TS

      ist das das einzige Subelement im Array, über das Du etwas wissen willst?

      Ja.

      Und definiere bitte "letzter Eintrag" etwas genauer.

      Die Arrayelemente sind schon chronologisch sortiert. Ich will das neueste mit haben, für das datePublished gesetzt ist, d.h. den neuesten Wert von datePublished im Array.

      🖖 Живіть довго і процвітайте

      --
      „Im Vergleich mit Elon Musk bei Twitter ist ein Elefant im Porzellanladen eine Ballerina.“
      — @Grantscheam auf Twitter
      1. Hello Gunnar,

        ist das das einzige Subelement im Array, über das Du etwas wissen willst?

        Ja.

        Und definiere bitte "letzter Eintrag" etwas genauer.

        Die Arrayelemente sind schon chronologisch sortiert.

        Das ist bei PHP-"Arrays" eine sehr gewagte Aussage.
        Wenn man nach dem Key geht, muss man unterscheiden, ob er numerisch, alphanumerisch, oder kombiniert (also sowohl numerische, als auch alphanumerische Schlüssel) enthält.

        Wenn man die (virtuelle) Baumstruktur mit next(), foreach(), oder ähnlichen Funktionen abläuft. dann kann man unter gewissen Umständen davon ausgehen, dass die Elemente chronologisch in den Teilketten (Subarrays) eingetragen werden, aber nur dann, wenn der jeweilige Key nicht schon vorhanden war. Dann würde das Element nämlich überschrieben werden.

        Ich will das neueste mit haben, für das datePublished gesetzt ist, d.h. den neuesten Wert von datePublished im Array.

        Ich nehme jetzt mal dein Beispiel, aber als "normales" Array und zerlege das in verständliche Einzelschritte:

        
        
        <?php
        $_list = array();  ## leere Liste erzeugen
        
        $_record = array();  ## leeren Datensatz bereitstellen
        $_record['name'] = 'The Next Generation';
        $_record['datePublished'] = '2023-02-16';
        
        $_list[] = $_record; ## Datensatz an Liste anfügen
        
        $_record = array();  ## leeren Datensatz bereitstellen
        $_record['name'] = 'Disengage';
        $_record['datePublished'] = '2023-02-13';
        
        $_list[] = $_record; ## Datensatz an Liste anfügen
        
        $_record = array();  ## leeren Datensatz bereitstellen
        $_record['name'] = 'Seventeen Seconds';
        
        $_list[] = $_record; ## Datensatz an Liste anfügen
        
        $_record = array();  ## leeren Datensatz bereitstellen
        $_record['name'] = 'No Win Scenario';
        
        $_list[] = $_record; ## Datensatz an Liste anfügen
        
        $_record = array();  ## leeren Datensatz bereitstellen
        $_record['name'] = 'Imposter';
        
        $_list[] = $_record; ## Datensatz an Liste anfügen
        
        $_record = array();  ## leeren Datensatz bereitstellen
        $_record['name'] = 'Bounty';
        
        $_list[] = $_record; ## Datensatz an Liste anfügen
        
        echo "<pre>\r\n";
        print_r($_list);
        
        ?>
        

        Das Obige verpackt man dann für den dynamischen Fall besser in einer Funktion. Wenn es tatsächlich eine Konstante werden soll, kann man das natürlich so ähnlich, wie Du es schon angedeutet hast in den Quellcode schreiben, ist aber hässlich.

        Ergibt folgende Ausgabe:

        Array
        (
            [0] => Array
                (
                    [name] => The Next Generation
                    [datePublished] => 2023-02-16
                )
        
            [1] => Array
                (
                    [name] => Disengage
                    [datePublished] => 2023-02-13
                )
        
            [2] => Array
                (
                    [name] => Seventeen Seconds
                )
        
            [3] => Array
                (
                    [name] => No Win Scenario
                )
        
            [4] => Array
                (
                    [name] => Imposter
                )
        
            [5] => Array
                (
                    [name] => Bounty
                )
        
        )
        

        Da das Array durch die Art der Eingabe (implizites array_push() mit reinem numerischen Schlüssel in der obersten Ebene erweitert wurde, liegen die Elemente automatisch in der Reihenfolge der Eintragung vor, egal, ob man das Array nach dem Key, oder mittels der "Baumfunktionen" abfragt.

        Du kannst das Array jetzt mit foreach() iterieren:

        
        $datePublished = '';
        $foundKey = NULL;
        foreach($_list as $key => $_record)
        {
        	if (isset($_record['datePublished']) && ($_record['datePublished'] > $datePublished))
        	{
        		$foundKey = $key;
        		$datePublished = $_record['datePublished'];
        	}
        }
        
        print_r($_list[$foundKey]); 
         
        

        ergibt dann die Ausgabe:

        Array
        (
            [name] => The Next Generation
            [datePublished] => 2023-02-16
        )  
        

        Du könntest das Array auch museumsmäßig nach den Keys iterieren, da diese hier alle vorhanden sein müssen. Wenn aber mal ein Record aus dre Liste gelöscht wurde, fehlt der Key. Dann gibt's Tüddel.

        Also besser foreach() benutzen.

        Glück Auf
        Tom vom Berg

        --
        Es gibt soviel Sonne, nutzen wir sie.
        www.Solar-Harz.de
        S☼nnige Grüße aus dem Oberharz
  2. Du könntest das Array umdrehen, durchlaufen und bei dem ersten Vorkommen des gewünschten Schlüssels das Element in eine Variable übernehmen und die Schleife verlassen:

    $s = false;
    
    foreach(array_reverse($array) AS $v)
      if(!empty($v['datePublished']) && $s=$v)
        break;
    

    Siehe Demo

    1. Hello Gast,

      könnte da ein Denkfehler drinstecken?

      array_reverse () kehrt nur die oberste Ebene der Baumstruktur in der Reihenfolge unter Neufestlegung der Schlüssel um.

      Ich bin mir jetzt nicht sicher, ob Gunnar das so gemeint hat:

      • finde den letzen Record, in dem ein datePublished gesetzt war

      oder ob er meinte:

      • finde das größte gesetzte datePublished?

      Du könntest das Array umdrehen, durchlaufen und bei dem ersten Vorkommen des gewünschten Schlüssels das Element in eine Variable übernehmen und die Schleife verlassen:

      $s = false;
      
      foreach(array_reverse($array) AS $v)
        if(!empty($v['datePublished']) && $s=$v)
          break;
      

      Siehe Demo

      Glück Auf
      Tom vom Berg

      --
      Es gibt soviel Sonne, nutzen wir sie.
      www.Solar-Harz.de
      S☼nnige Grüße aus dem Oberharz
      1. Hallo,

        Ich bin mir jetzt nicht sicher, ob Gunnar das so gemeint hat:

        • finde den letzen Record, in dem ein datePublished gesetzt war

        ich denke, nein.

        oder ob er meinte:

        • finde das größte gesetzte datePublished?

        So habe ich ihn jedenfalls verstanden.

        Einen schönen Tag noch
         Martin

        --
        Möchtegern-Dichter zum Verleger: "Sie meinen also, ich sollte etwas mehr Feuer in meine Verse legen?" - "Umgekehrt, mein Lieber, umgekehrt. Mehr Verse ins Feuer."
      2. @@TS

        Ich bin mir jetzt nicht sicher, ob Gunnar das so gemeint hat:

        • finde den letzen Record, in dem ein datePublished gesetzt war

        oder ob er meinte:

        • finde das größte gesetzte datePublished?

        Da – wie ich schrub – das Array chronologisch sortiert ist, sollte das dasselbe sein.

        Das Array wird einmalig erstellt (aus JSON-LD, s.a. dieses Posting) und danach nicht mehr geändert.

        🖖 Живіть довго і процвітайте

        --
        „Im Vergleich mit Elon Musk bei Twitter ist ein Elefant im Porzellanladen eine Ballerina.“
        — @Grantscheam auf Twitter
        1. Hello,

          Ich bin mir jetzt nicht sicher, ob Gunnar das so gemeint hat:

          • finde den letzen Record, in dem ein datePublished gesetzt war

          oder ob er meinte:

          • finde das größte gesetzte datePublished?

          Da – wie ich schrub – das Array chronologisch sortiert ist, sollte das dasselbe sein.

          Das Array wird einmalig erstellt (aus JSON-LD, s.a. dieses Posting) und danach nicht mehr geändert.

          Das Array ist also sowieso nach 'datePublished' sortiert?
          Dann müssten die Einträge ohne 'datePublished' der Ordnung halber aber am Anfang stehen ;-P

          Wenn Du Dir über die Konsistenz der Datenherkunft absolut sicher bist, kann das klappen, wie Gast es schrieb.

          Ob eine eventuell schnellere Abarbeitung aber den Sicherheitsverlust wieder wett macht, bleibt Dir überlassen.

          Immerhin könnte ja auch der letzte Datensatz im Array noch ein datePublished enthalten. Dann würde das Array ohnehin bis zum Ende iteriert werden müssen.

          Irrtum meinerseits. Es muss heißen: "der erste Datesatz" (der ursprünglichen Daten).
          Der würde nach dem array_reverse() dann nämlich der letzte sein.

          Und das array_reverse benötigt auch ein paar Zyklen.

          Den ersten Teil meiner Betrachtung benötigst Du ja nicht. Der war nur zur Nachvollziehbarkeit des zweiten vorhanden.

          Glück Auf
          Tom vom Berg

          --
          Es gibt soviel Sonne, nutzen wir sie.
          www.Solar-Harz.de
          S☼nnige Grüße aus dem Oberharz
      3. Hallo TS!

        Die Arrayelemente sind schon chronologisch sortiert.

        Ich ging davon aus, dass das neueste Datum zuletzt gereiht ist. Wenn das Array umgedreht wird und dann das erste Element, welches ein Datum enthält genommen wird, dann sollte es dem jüngsten Datum entsprechen... dachte ich :D

        Wenn's anders herum sortiert ist das array_reverse weglassen.

        1. Hello Gast,

          Die Arrayelemente sind schon chronologisch sortiert.

          Ich ging davon aus, dass das neueste Datum zuletzt gereiht ist. Wenn das Array umgedreht wird und dann das erste Element, welches ein Datum enthält genommen wird, dann sollte es dem jüngsten Datum entsprechen... dachte ich :D

          Wenn's anders herum sortiert ist das array_reverse weglassen.

          Für den von Gunnar (nachträglich) näher beschriebenen Spezialfall stimmt das selbstverständlich.

          Das wäre mir pesönlich aber nicht eigensicher genug.

          Eine Funktion sollte immer ein definiertes Ergebnis liefern, auch wenn in den Randbedingungen etwas geändert wird. Man verlässt sich dann später oft genug auf "wird schon passen", und ändert an anderer Stelle leichtfertig etwas. Schon fällt das Kind in den Brunnen.

          Das war auch der Grund für meine ausführliche Einleitung.

          Glück Auf
          Tom vom Berg

          --
          Es gibt soviel Sonne, nutzen wir sie.
          www.Solar-Harz.de
          S☼nnige Grüße aus dem Oberharz
  3. Die Liste der der Array-Funktionen von PHP ist einsehbar. Darin findet sich:

    Dort lese ich:

    iteriert über jeden Wert im Array array und übergibt diesen der Callbackfunktion callback. Gibt die Funktion callback true zurück, so wird der aktuelle Wert von array in das Ergebnis-Array geschrieben.

    Dann musst Du aus dem Ergebnis-Array nur noch das letzte Element holen. Das geht bequem mit array_shift( array_reverse( ) ):

    $last = array_shift( 
      array_reverse( 
         array_filter( ... )
      ) 
    );
    

    Alternativ kannst Du auch ganz stumpf und einfach mit foreach iterieren, das jeweilige Element untersuchen und, wenn es passt, das Element als temporäres Ergebnis übernehmen. Wenn das foreach alles durchgehechelt hat, ist Dein temporäres Ergebnis das Endergebnis. Ja: Das ist so einfach, wie es klingt.

    • Würdest Du beim ersten Fund abbrechen, dann hättest etwas analoges zu „array.findFirst()“.
    • Oder Du brichts beim ersten Fund ab, machst das aber mit dem revertierten Array. Dann hast Du auf eine teure Weise aus „array.findFirst()“ „array.findLast()“ gemacht.

    Ich verwette meinen Popo, dass Java letztendlich auch nichts anderes als etwas von obigem macht.

    Es muss nicht für jeden „selten benutzten Mist“ eine fertige Funktion geben. Sonst hat man so viele Funktionen, dass keiner mehr die „richtige“ kennt und erst recht keiner mehr aus dem Hut sagen kann, wie es denn mit der Performance aussähe, wenn man denn statt diesem jenes tue.

    1. Hallo Raketenwilli,

      array_shift(array_reverse(...))

      array_shift und array_unshift agieren am Array-Anfang.
      array_push und array_pop agieren am Array-Ende.

      Ich würde demnach array_pop empfehlen.

      Ob sich array_pop auf das Rückgabearray von array_filter anwenden lässt, weiß ich allerdings auch nicht, müsste ich probieren.

      Ich persönlich würde mich auch nicht unbedingt auf die "ist vorsortiert" Aussage verlassen wollen. Das kann zur Zeit stimmen, aber man handelt sich damit eine Abhängigkeit ein (zwischen HTML Ausgabe und JSON-LD Verarbeitung) ein, die architektonisch nicht wünschenswert ist. Deshalb würde ich für eine funktionale Lösung erst filtern, dann das Array aufsteigend usortieren und danach array_pop verwenden. Das ist aber aufwändig.

      Die einfachste, verständlichste und schnellste Lösung sollte Toms funktionsloser Vorschlag mit dem foreach-Durchlauf sein, der einfach den Satz findet, der das Maximum von date_published enthält.

      Offene Frage: Was ist bei zwei Einträgen mit gleichem maximalen date_published? Welchen nimmt man?

      Rolf

      --
      sumpsi - posui - obstruxi
      1. Hello,

        Offene Frage: Was ist bei zwei Einträgen mit gleichem maximalen date_published? Welchen nimmt man?

        Sehr gute Frage!

        Den Fall hatte ich - zugegeben - auch noch nicht im Kopf.
        Aber wirklich interessant!

        Glück Auf
        Tom vom Berg

        --
        Es gibt soviel Sonne, nutzen wir sie.
        www.Solar-Harz.de
        S☼nnige Grüße aus dem Oberharz
      2. Ob sich array_pop auf das Rückgabearray von array_filter anwenden lässt, weiß ich allerdings auch nicht, müsste ich probieren.

        Die Antwort ist „Jein“. In meinen Experimenten hat das funktioniert - aber PHP warnt:

        • PHP Notice: Only variables should be passed by reference ...

        Lösung: Das Rückgabearray von array_filter in einen helper-Array schreiben und dann wie [ array_pop, array_shift, ...] auf den helper-Array anwenden.

        In diesem speziellen Fall kann man die Notiz aber ebenso ignorieren, weil man ja den Array gar nicht verändern will, das „liefert“ reicht, das „entfernt“ wird ja tatsächlich nicht benötigt. Das geht natürlich nur wenn man nicht an anderer Stelle - aus durchaus gutem Grund - aus Warnungen und/oder Notizen fatale Fehler gemacht hat.

      3. Ich persönlich würde mich auch nicht unbedingt auf die "ist vorsortiert" Aussage verlassen wollen.

        Also wenn man vorliegend die Fragestellung anzweifelt, dann kann man gar nicht anders antworten als mit einem „RTFM!“ - denn dann könnte man ja sich z.B. schon fragen ob es überhaupt um PHP geht ...

        1. Dieser Beitrag wurde gesperrt: Der Beitrag ist außerhalb des durch dieses Forum abgedeckten Themenbereichs.

          Hallo,

          Ich persönlich würde mich auch nicht unbedingt auf die "ist vorsortiert" Aussage verlassen wollen.

          Also wenn man vorliegend die Fragestellung anzweifelt, ...

          "Die Fragestellung solltet ihr nicht in Frage stellen."
          Sagte Kai Pflaume vor einiger Zeit zu seinen Quizkandidaten in "Wer weiß denn sowas".

          Einen schönen Tag noch
           Martin

          --
          Möchtegern-Dichter zum Verleger: "Sie meinen also, ich sollte etwas mehr Feuer in meine Verse legen?" - "Umgekehrt, mein Lieber, umgekehrt. Mehr Verse ins Feuer."
          1. "Die Fragestellung solltet ihr nicht in Frage stellen."

            Zumal ich von Gunnar ja nicht erwarten würde, dass der dieses Problem falsch formuliert oder, falls doch, das nicht inzwischen korrigiert hat.

            Falls es mir aus sich wirklich aufdrängenden Gründen geboten erscheint, mache ich das durchaus. Ist ja keine Quiz-Show.

            "Wer weiß denn sowas".

            Hab ich mal im Hotel geschaut: Gegen mich wollen die echt nicht antreten. Und ich habe gerade mal ein ganz klein wenig mehr als durchschnittliche Intelligenz…

            1. Hallo Raketenwilli,

              hier ist Selfhtml. Und da ist es gute Tradition, die angenommen Invarianten des TO in Zweifel zu ziehen. Deswegen brauchst Du mich nicht anzupflaumen (SCNR😉).

              Ist es eine sinnvolle Vorgehensweise, von einer vorsortierten Datenstruktur auszugehen? Das ist es, wie begründet, nicht. Man schafft damit eine technische Schuld bei dem Programmteil, der das HTML mit den Metadaten erzeugt, er muss diese Invariante beachten und darf sie nie verletzen.

              Rolf

              --
              sumpsi - posui - obstruxi
            2. Hallo,

              "Wer weiß denn sowas".

              Hab ich mal im Hotel geschaut: Gegen mich wollen die echt nicht antreten.

              bei mir käme es sehr auf die zur Wahl stehenden Kategorien an. Bei Damals, Im Grünen, Sport oder Royals sehe ich als mitratender Zuschauer im Sessel meist ziemlich alt aus. Kategorien wie Technik, Clever, Straßenverkehr oder Im Labor kann ich dagegen meist ohne große Mühe beantworten. Manchmal sogar offen, also ohne die Antwortmöglichkeiten überhaupt zu sehen.

              Aber ich schau die Sendung gern - ich find' sie witzig und unterhaltsam, und es besteht durchaus die Gefahr, dass ich noch was dabei lerne.

              Einen schönen Tag noch
               Martin

              --
              Möchtegern-Dichter zum Verleger: "Sie meinen also, ich sollte etwas mehr Feuer in meine Verse legen?" - "Umgekehrt, mein Lieber, umgekehrt. Mehr Verse ins Feuer."
            3. Hallo Raketenwilli,

              Gegen mich wollen die echt nicht antreten.

              Dann los, bewirb Dich. Sag Bescheid, wann Du auf Sendung bist. Als der Schrecken der Kasseler Justiz gehst Du als Z-Promi durch und brauchst nur noch einen passenden Gegenspieler. Günni wäre geeignet, ist leider nicht mehr onlive. Wenn Pflaume Dich nicht will, probier's beim Bommes. Der Besserwisser jagt den Besserschlosser, das wär mal was.

              Spaß beiseite, vermutlich ist genau das der Sinn der Sendung. Es ist ja auch nicht so, dass Hoëcker und Elton besondere Quizgötter wären. Der Zuschauer soll gut mitraten können, soll sich dabei gut fühlen und die Fragen sind ja auch oft so gestellt, dass man die Antwort im Ausschlussverfahren findet.

              Ups. Der Thread entgleist 😉

              Rolf

              --
              sumpsi - posui - obstruxi
              1. Spaß beiseite, vermutlich ist genau das der Sinn der Sendung.

                Jepp. Die Zuschauer können anderen beim „Herumeiern“ zusehen und sich gut fühlen. Sind ja nicht umsonst überwiegend Komiker dort.

                1. Spaß beiseite, vermutlich ist genau das der Sinn der Sendung.

                  Jepp. Die Zuschauer können anderen beim „Herumeiern“ zusehen und sich gut fühlen. Sind ja nicht umsonst überwiegend Komiker dort.

                  Sagt der, der die Sendung "mal im Hotel geschaut" hat. Bin da komplett beim Martin. Die Sendung ist amüsant und man lernt durchaus was, gerne auch im skurrilen Bereich, was es dann gerade noch amüsanter macht.

                  Aber das ist für Menschen mit Deinem IQ natürlich alles profan.

                  1. Sagt der, der die Sendung "mal im Hotel geschaut" hat.

                    Bin, beruflich bedingt, im Winter oft im Hotel. Und bei 1′C, starkem Wind, Nebel und Dunkelheit hat man weniger oft Lust auf einen Stadtspaziergang. Für den Sommer hab ich was besseres, da kann ich an einem Badesee, Kiesteich oder Fluss logieren.

                    Aber das ist für Menschen mit Deinem IQ natürlich alles profan.

                    Du meinst den, den ich mit …

                    Und ich habe gerade mal ein ganz klein wenig mehr als durchschnittliche Intelligenz…

                    ... beschrieben hatte? Kann es sein, dass Du in einer, ziemlich verwerflich anmutenden Absicht, einem uninformierten Leser gezielt wahrheitswidrig vormachen willst, ich hätte mich eines besonders hohen IQs berühmt?

              2. Hallo Rolf,

                Günni [...] onlive.

                touché. 😀

                Wenn Pflaume Dich nicht will, probier's beim Bommes.

                Das ist besser. Da sind die Gäste normalerweise Nicht-Prominente.

                Der Besserwisser jagt den Besserschlosser, das wär mal was.

                🤣

                Einen schönen Tag noch
                 Martin

                --
                Möchtegern-Dichter zum Verleger: "Sie meinen also, ich sollte etwas mehr Feuer in meine Verse legen?" - "Umgekehrt, mein Lieber, umgekehrt. Mehr Verse ins Feuer."
                1. Wenn Pflaume Dich nicht will, probier's beim Bommes. Das ist besser. Da sind die Gäste normalerweise Nicht-Prominente.

                  Das Level der Fragen ist m.E. auch deutlich höher. Hilfreich, damit Raketen-IQ sich am Ende nicht unterfordert fühlt.

                  1. Wenn Pflaume Dich nicht will, probier's beim Bommes. Das ist besser. Da sind die Gäste normalerweise Nicht-Prominente.

                    Das Level der Fragen ist m.E. auch deutlich höher. Hilfreich, damit Raketen-IQ sich am Ende nicht unterfordert fühlt.

                    Was aber nach meiner Ansicht weniger mit einem hohen IQ als mit dem von mir gottlob unterlassenem „das Hirn kaputtsaufen“ zu tun hat.

              3. @@Rolf B

                Ups. Der Thread entgleist 😉

                Wenn ich jetzt ein N00b wäre, würde ich mich sowas von darüber beschweren!!1elf

                🖖 Живіть довго і процвітайте

                --
                „Im Vergleich mit Elon Musk bei Twitter ist ein Elefant im Porzellanladen eine Ballerina.“
                — @Grantscheam auf Twitter
          2. Hallo an die Entgleiser, vor allem den Mitleser 2.0,

            Ups. Der Thread entgleist 😉

            Und weil es jetzt auch noch gehässig wird, dreh ich nun den Schlüssel rum.

            Rolf

            --
            sumpsi - posui - obstruxi
      4. @@Rolf B

        Ich persönlich würde mich auch nicht unbedingt auf die "ist vorsortiert" Aussage verlassen wollen. Das kann zur Zeit stimmen, aber man handelt sich damit eine Abhängigkeit ein (zwischen HTML Ausgabe und JSON-LD Verarbeitung) ein, die architektonisch nicht wünschenswert ist.

        Ich hätte „sollte das dasselbe sein“ ergänzen sollen um: egal, ob’s dasselbe ist: nimm das letzte Element mit der Eigenschaft datePublished.

        Das Template soll die Daten anzeigen. Was beïnhaltet, bei unvollständigen Daten keinen Fehler zu werfen, sondern die vorhandenen anzuzeigen. Was aber nicht beïnhaltet, die Daten zu prüfen.

        Wenn im letzten Element mit der Eigenschaft datePublished nicht der neueste überhaupt vorkommende Wert von datePublished steht, dann sind die Daten falsch. Das Template soll die Daten anzeigen, nicht mehr und nicht weniger.

        Deshalb würde ich für eine funktionale Lösung erst filtern, dann das Array aufsteigend usortieren und danach array_pop verwenden. Das ist aber aufwändig.

        Ich gehe jetzt schon davon aus, dass die JSON-LD-Daten sortiert sind. Ansonsten müsste ich erst das Array mit den Staffeln nach deren Nummer und innerhalb jeder Staffel die Arrays mit den Episoden nach deren Nummer sortieren. Das spare ich mir; ich gebe die Daten in der Reihenfolge aus, wie sie im JSON-LD stehen.

        🖖 Живіть довго і процвітайте

        --
        „Im Vergleich mit Elon Musk bei Twitter ist ein Elefant im Porzellanladen eine Ballerina.“
        — @Grantscheam auf Twitter
        1. @@Gunnar Bittersmann

          Wenn im letzten Element mit der Eigenschaft datePublished nicht der neueste überhaupt vorkommende Wert von datePublished steht, dann sind die Daten falsch.

          Oder auch nicht.

          Der Pilotfilm „The Cage“ (mit Pike als Captain der Enterprise) zu The Original Series (mit Kirk als Captain) wurde erst knapp 20 Jahre nach deren Ende ausgestahlt.

          Und nochmal über 30 Jahre später fanden sich Ausschnitte daraus im Vorspann der Folge 2.8 „If Memory Serves“ von Discovery wieder. „Zuletzt bei Star Trek: …“

          🖖 Живіть довго і процвітайте

          --
          „Im Vergleich mit Elon Musk bei Twitter ist ein Elefant im Porzellanladen eine Ballerina.“
          — @Grantscheam auf Twitter
          1. @@Gunnar Bittersmann

            Und nochmal über 30 Jahre später fanden sich Ausschnitte daraus im Vorspann der Folge 2.8 „If Memory Serves“ von Discovery wieder.

            Welche übrigens gerade auf Pluto.tv läuft. Und um Mitternacht noch mal. Meine Lieblingsfolge der 2. Staffel.

            🖖 Живіть довго і процвітайте

            --
            „Im Vergleich mit Elon Musk bei Twitter ist ein Elefant im Porzellanladen eine Ballerina.“
            — @Grantscheam auf Twitter
          2. Und nochmal über 30 Jahre später fanden sich Ausschnitte daraus im Vorspann der Folge 2.8 „If Memory Serves“ von Discovery wieder. „Zuletzt bei Star Trek: …“

            Wenn ich den Link samt Hashtag direkt anklicke, dann "sehe" ich, dass der so Anker angesprungen wird, dass ich ihn auch sehe. Wenn auch verzögert, da greift also irgendein JS.

            Wenn ich den Link samt Hashtag aber in einem neuem Tab öffne, scheint das JS sein Werk nicht verrichten und das eigentliche Ziel 2.8. wird vom Sticker-Header überlagert, man muss also hochscrollen um das gewünschte 2.8. zu sehen. Nicht so schön.

            1. @@Mitleser 2.0

              Und nochmal über 30 Jahre später fanden sich Ausschnitte daraus im Vorspann der Folge 2.8 „If Memory Serves“ von Discovery wieder. „Zuletzt bei Star Trek: …“

              Wenn ich den Link samt Hashtag direkt anklicke, dann "sehe" ich, dass der so Anker angesprungen wird, dass ich ihn auch sehe. Wenn auch verzögert, da greift also irgendein JS.

              Wenn ich den Link samt Hashtag aber in einem neuem Tab öffne, scheint das JS sein Werk nicht verrichten und das eigentliche Ziel 2.8. wird vom Sticker-Header überlagert, man muss also hochscrollen um das gewünschte 2.8. zu sehen. Nicht so schön.

              Danke für die Fehlermeldung. Das Verhalten kann ich nachvollziehen. Meh. Mal sehen, was ich da tun muss …

              🖖 Живіть довго і процвітайте

              --
              „Im Vergleich mit Elon Musk bei Twitter ist ein Elefant im Porzellanladen eine Ballerina.“
              — @Grantscheam auf Twitter
              1. @@Gunnar Bittersmann

                Mal sehen, was ich da tun muss …

                Sofort nach dem Rendern der Seite die Höhe des Headers in die custom property schreiben, damit sie für scroll-padding-top rechtzeitig zur Verfügung steht. Der ResizeObserver tut’s beim Laden in einen neuen Tab nicht.

                Änderungen

                🖖 Живіть довго і процвітайте

                --
                „Im Vergleich mit Elon Musk bei Twitter ist ein Elefant im Porzellanladen eine Ballerina.“
                — @Grantscheam auf Twitter
  4. @@Gunnar Bittersmann

    und möchte das letzte Element finden, das eine bestimmte Eigenschaft hat

    Ich hab nochmal über meinen Anwendungsfall sinniert und bin zu dem Schluss gekommen, dass ich das gar nicht brauche.

    Ich möchte bei einer aktuellen Staffel zusätzliche Links zu Wikipedia-Artikeln (sofern solche in den Daten hinterlegt sind) im Footer anzeigen; so wie es derzeit bei Picard der Fall ist, bei den anderen Serien aber nicht.

    Dazu muss ich mir aber nur das letzte Element der letzten Staffel ansehen – zweimal end(). Wenn dieses kein datePublished hat, ist die Staffel aktuell. Wenn es eins hat und der Wert in nicht allzu ferner Vergangenheit liegt, ist die Staffel aktuell. (Ob „in nicht allzu ferner Vergangenheit“ nun ein Monat oder ein Jahr bedeutet, muss ich mir noch überlegen.)

    Aber schön, dass wir drüber gespochen haben. 😉

    🖖 Живіть довго і процвітайте

    --
    „Im Vergleich mit Elon Musk bei Twitter ist ein Elefant im Porzellanladen eine Ballerina.“
    — @Grantscheam auf Twitter
  5. @@Gunnar Bittersmann

    In JavaScript kein Problem.

    Oder doch? TIL, dass es findLast() und findLastIndex() in Node erst ab Version 18 gibt.

    🖖 Живіть довго і процвітайте

    --
    „Im Vergleich mit Elon Musk bei Twitter ist ein Elefant im Porzellanladen eine Ballerina.“
    — @Grantscheam auf Twitter
    1. Hallo Gunnar,

      was erwartest Du denn auch? Node 16 ist die Version von 2021 und seit fast einem Jahr nicht mehr die LTS Version, und diese Array-Methoden sind ECMAScript 2023.

      Node 16 hat immer eine 9.x Version von V8 enthalten (Beleg). Es hat mit 9.0 begonnen und wurde zuletzt am 23.9.22 auf 9.4.146.26 (aus Blink 94) gepatcht.

      Die V8 v10.1 Engine, in der findLast und findLastIndex implementiert wurden, gehört zu Blink 101 (26.04.22) und ist mit Node 18 (19.04.2022) eingeführt worden.

      Ich würde annehmen, dass ein Sprung der V8 Major-Version zu gravierend ist, um sie in ein minor Update von Node einzupflegen. Vor allem, wenn es nicht mehr die LTS Version ist.

      Das Problem bei Node.js ist allerdings, dass ältere Versionen sich deutlich länger halten als bei den Browsern (vom ZombIE mal abgesehen). Bei neuen Sprachfeatures, die man auf node.js einsetzen will, muss man also genau hinschauen und im Zweifelsfall auch mal Juriy Zaytsev befragen. Leider ist diese Seite ziemlich unübersichtlich und hat keine Suchfunktion, um in die eingeklappten Teile hineinzuschauen.

      Rolf

      --
      sumpsi - posui - obstruxi