Miky: Zahlen in einer For-Schleife durchlaufen lassen und überprüfen

Hallo Zusammen,

gerne möchte ich diese If-Überprüfungen in einer Schleife automatisch durchlaufen lassen. Danke für eure Denkanstösse.

Gruss Miky

$zahl1_oben  = "30";
$zahl1_unten = "10";

$zahl2_oben  = "40";
$zahl2_unten = "20";

$zahl3_oben  = "35";
$zahl3_unten = "15";

$zahl4_oben  = "22";
$zahl4_unten = "5";

$zahl5_oben  = "45";
$zahl5_unten = "22";


if($zahl1_oben < $zahl2_oben) {
  // zahl ist höher, also nächste zahlen überprüfen
  echo "höher <br/>";
  echo "nächste überprüfung...<br/>";
} else {
  if($zahl1_unten < $zahl2_unten) {
    // die zahl ist nicht tiefer
    echo "nicht tiefer <br/>";
    if($zahl1_oben < $zahl2_oben) {
      // zahl ist höher, also nächste zahlen überprüfen
      // z.b = if($zahl4_oben < $zahl5_oben)
      echo "höher 2.0 <br/>";
      echo "nächste überprüfung...<br/>";
    }
  } else {
    // die zahl ist tiefer
    echo "zahl ist tiefer <br/>";
    if($zahl1_oben < $zahl2_unten) {
        // treffer
        echo "treffer <br/>";
    } else {
        // kein treffer, warten bis es einen treffer gibt.
        echo "kein treffer <br/>";
    }

  }
}

// Überprüfungen von den 4 Ifs

  1. if($zahl1_oben < $zahl2_oben)

Ist höher, also nächste überprüfungung hier geht man zu den nächsten zahlen, sprich if($zahl2_oben < $zahl3_oben), if($zahl3_oben < $zahl4_oben), if($zahl4_oben < $zahl5_oben)... usw.

  1. if($zahl2_oben < $zahl3_oben) Zahl ist tiefer

also weiter zum 4. if

  1. if($zahl2_oben < $zahl3_oben) = kein treffer

solange überprüfen bis eine höhere zahl kommt

if($zahl2_oben < $zahl4_oben) = kein treffer

if($zahl2_oben < $zahl5_oben) = treffer!

  1. Hello,

    Du willst also den größten bzw. kleinsten Wert finden und eventuell noch dessen Position?

    Dann ist das eine Aufgabe für ein Array, die foreach()-Anweisung und ein zusätzliches Zwischspeicherelement. Für den Vergleich gibt es außerdem noch die Funktionen min() und max().

    Werte, die einen gemeinsamen Bezug zueinander haben, sollte man nicht in Skalaren ("losen Variablen") speichern, sondern in Arrays.

    Glück Auf
    Tom vom Berg

    --
    Es gibt nichts Gutes, außer man tut es!
    Das Leben selbst ist der Sinn.
  2. Hallo Miky,

    gerne möchtest Du uns erklären, was Du eigentlich beabsichtigst.

    Und du solltest - sofern es keine zwingenden Gründe für das Gegenteil gibt - Zahlen als Zahlen verarbeiten und nicht als Strings. Also 30 statt "30". Warum? Für dich am wichtigsten ist: Der Vergleich if ("5" < "15") ergibt FALSCH. Dagegen ergibt if (5 < 15) wunschgemäß WAHR.

    Dein Code-Fragment ist offenbar nur ein Teil für die beiden ersten Zahlenpaare.

    Aber: Was bedeuten diese Zahlenpaare, was ist der Sinn der Vergleiche? Deine Erklärung dessen, was Du tun willst, ist ohne Kenntnis deiner Absichten völlig unverständlich. Es ist unklar, wann Du benachbarte Paare (z.B. zahl1/zahl2) oder weiter entfernte Paare (z.B. zahl2/zahl4) vergleichen willst.

    Das grundsätzliche Mittel der Wahl für Aufgaben dieser Art ist das https://www.php.net/manual/de/language.types.array.phpArray. Die Erklärung auf php.net ist eher eine Expertenversion. Unser Wiki enthält einen rudimentären PHP Teil, wo aber auch eine Erklärung zu Arrays drin ist.

    $zahlen = ARRAY(
       ARRAY("oben" = 30, "unten" => 10),
       ARRAY("oben" => 40, "unten" => 20),
       ARRAY("oben" => 35, "unten" => 15),
       ARRAY("oben" => 22, "unten" => 5),
       ARRAY("oben" => 45, "unten" => 22),
    );
    

    Das Komma nach dem letzten ARRAY(...) sieht falsch aus, das war auch mal so, aber mittlerweile lässt PHP das zu, damit man nicht beim Hinzufügen oder Löschen von Zeilen in solchen Konstrukten ständig auf die Kommas aufpassen muss.

    In neueren PHP Versionen (ab 5.6, meine ich) kann man das umständliche ARRAY auch durch eckige Klammern ersetzen:

    $zahlen = [
       [ "oben" => 30, "unten" => 10 ],
       [ "oben" => 40, "unten" => 20 ],
       [ "oben" => 35, "unten" => 15 ],
       [ "oben" => 22, "unten" =>  5 ],
       [ [oben" => 45, "unten" => 22 ],
    ];
    

    Das Array enthält nun Einträge mit den Indexen 0-4 (statt 1-5), und zu kommst an den dritten "unten"-Wert so heran: $zahlen[2]["unten"]. Das sieht erstmal umständlicher aus, aber an Stelle von 2 oder "unten" kannst du auch Variablen einsetzen und bist damit flexibel.

    Was man Dir an Code vorschlagen kann, hängt nun von deinen Absichten ab. Erzähl mal.

    Rolf

    --
    sumpsi - posui - clusi
    1. Vielen Dank Zusammen

      Also ich möchte folgendes. Die Reihenfolge ist auch wichtig immer von oben nach unten im Array, sprich $zahlen[0] $zahlen[1] $zahlen[2] ....

      $zahlen = [
         [ "oben" => 30, "unten" => 10 ],
         [ "oben" => 40, "unten" => 20 ],
         [ "oben" => 35, "unten" => 15 ],
         [ "oben" => 22, "unten" =>  5 ],
         [ "oben" => 45, "unten" => 22 ],
      ];
      
      1. Zuerst muss ich mit den ersten beiden Zahlen ermittel welche die höchste ist "oben" $zahlen[0]["oben"] < $zahlen[1]["oben"], in diesem Fall die 40.

      2. Jetzt muss zuerst die Zahl von dem Array $zahlen[1]["unten"] also die 20 einmal mit den nachfolgenden Zahlen unterschritten werden. Mit der 3. Zahl passiert es $zahlen[2]["unten"] gleich die 15

      3. Und jetzt wenn mit der 4., 5., .6 Zahl usw. die 40, $zahlen[1]["oben"] überschritten wird, habe ich ein Treffer. Mit der 4. passiert dies noch nicht weil "oben" 22, aber mit der 5. $zahlen[4]["oben"] die 45.

      Jetzt weiss ich nur noch nicht wie ich das in einem foreach automatisieren kann.

      Miky

      1. Hallo Miky,

        du hast schon viel gewonnen, wenn Du es schaffst, deine Aufgabenstellung nicht in Form eines Beispiels zu formulieren, sondern in Form einer "Wenn dies, dann das" Beschreibung. Dabei fällt dann auch auf, ob es "dies" Situationen gibt, zu denen man sich noch kein "das" überlegt hat.

        Da Du nicht beschreibst, was Du tun willst, sondern nur, wie Du es tun willst, kann ich mir etliche der folgenden Fragen nicht selbst beantworten.

        Was ich im Moment aus deiner Beispielbeschreibung herauslese, ist:

        Suche Dir von den beiden ersten Array-Einträgen den mit dem größeren "oben" Wert. Dessen Index sei $i.

        Frage: Was ist, wenn beide gleich sind? Das ist nicht egal, denn sie können ja gleiche "oben" Werte haben, aber verschiedene "unten" Werte.

        Suche ab Index 2 einen Eintrag, dessen "unten" Eintrag kleiner ist als der von Zeile $i. Der Index dieses Eintrags sei $j.

        Frage: Was ist, wenn $i nicht 1 ist, wie im Beispiel, sondern 0. Müsste man dann auch ab Index 2 suchen? Oder ab Index 1?

        Prüfe für den Rest des Arrays, ob die "oben" Werte größer sind als der "oben" Wert am Index $i.

        Frage: Was ist "Rest"? Der Index ab $j + 1?

        Was dann noch zu klären wäre, ist: Weißt Du, wie Du deine Zahlenpaare aus der Datenquelle ordentlich ins Array hineinbekommst?

        Ein Hinweis noch: foreach wird Dir vermutlich nicht helfen. Damit werden immer alle Einträge des Arrays verarbeitet. Du musst aber ab einem bestimmtem Wert beginnen. Es wird wohl auf die klassische for (;;) Schleife hinauslaufen.

        Rolf

        --
        sumpsi - posui - clusi
        1. Hello,

          Ein Hinweis noch: foreach wird Dir vermutlich nicht helfen. Damit werden immer alle Einträge des Arrays verarbeitet. Du musst aber ab einem bestimmtem Wert beginnen. Es wird wohl auf die klassische for (;;) Schleife hinauslaufen.

          Das stimmt nicht.

          Es gibt continue und break, mit denen man den Ablauf in einem Foreach-Konstrukt sehr einfach steuern kann.

          Außerdem könnte es hilfreich sein, zunächst das eigentliche Problem zu schildern und nicht gleich seine vermeintliche programmierte Abbildung/Lösung.

          Glück Auf
          Tom vom Berg

          --
          Es gibt nichts Gutes, außer man tut es!
          Das Leben selbst ist der Sinn.
          1. Außerdem könnte es hilfreich sein, zunächst das eigentliche Problem zu schildern und nicht gleich seine vermeintliche programmierte Abbildung/Lösung.

            Das eigentliche Problem ist die Abwesenheit einer zweckmäßigen Datenstruktur. Denn die zu vergleichenden Zahlen stehen ja in irgendeiner Beziehung zueinander, das heißt daß es etwas gibt was die miteinander verbindet. Von daher ist der Vorschlag mit dem Array schonmal ein sehr guter Schritt in Richtung Lösung. Heißt außerdem, daß die Lösung bereits mit der Datenerfassung beginnt.

            MFG

          2. Hallo,

            Ein Hinweis noch: foreach wird Dir vermutlich nicht helfen. Damit werden immer alle Einträge des Arrays verarbeitet. Du musst aber ab einem bestimmtem Wert beginnen. Es wird wohl auf die klassische for (;;) Schleife hinauslaufen.

            Das stimmt nicht.

            vielleicht nicht; vielleicht doch. Je nach Anwendungsfall kann foreach eine gute Alternative zur traditionellen for-Schleife sein, eventuell sogar besser.
            Vor allem wenn die Indexe nicht numerisch oder nicht lückenlos aufeinander folgend sind, kann foreach wesentlich günstiger sein.

            Es gibt continue und break, mit denen man den Ablauf in einem Foreach-Konstrukt sehr einfach steuern kann.

            Ja, aber das gilt für die gute alte for-Schleife auch.

            Außerdem könnte es hilfreich sein, zunächst das eigentliche Problem zu schildern und nicht gleich seine vermeintliche programmierte Abbildung/Lösung.

            Bingo. Ich weiß nicht, ob ich der einzige bin - aber die eigentliche Aufgabe habe ich auch immer noch nicht verstanden.

            Ciao,
             Martin

            --
            Computer müssen weiblich sein: Eigensinnig, schwer zu durchschauen, immer für Überraschungen gut - aber man möchte sie nicht missen.
          3. Hallo TS,

            foreach (verarbeitet immer) alle Einträge des Arrays.

            Das stimmt nicht.

            Okay - von break und continue habe ich mal abgesehen.

            Jedoch: Wenn es um dies hier geht:

            Du musst aber ab einem bestimmtem Wert beginnen.

            dann ist foreach nicht mehr das Mittel der Wahl. Wenn ich ab Position 7 beginnen muss, ist es unschick, im foreach erstmal bis 7 zu zählen und den Schleifenrumpf mit continue zu umgehen. Analog zu LinQ in C# könnte man sich Iteratoren bauen, die Arrayelemente überspringen können, aber das würde hier im Thread nur zur finalen Verwirrung des OP führen 😂

            Außerdem könnte es hilfreich sein, zunächst das eigentliche Problem zu schildern

            Amen. A/B Problemquiz zu spielen ist blöde. Wie ich schon als allererstes sagte:

            gerne möchtest Du uns erklären, was Du eigentlich beabsichtigst.

            Und damit meinte ich nicht, welche Variable wie zu setzen ist, sondern die fachliche Aufgabenstellung.

            Rolf

            --
            sumpsi - posui - clusi
            1. Hello Rolf,

              Jedoch: Wenn es um dies hier geht:

              Du musst aber ab einem bestimmtem Wert beginnen.

              • Ab einem bestimmten Wert?
              • Ab einem bestimmten Element?
              • Ab einer bestimmten Position (7. Element in der Kette)?
              • Ab einem bestimmten Index?

              Das Problem ist, dass "Arrays" in PHP nur virtuell einen wahlfreien Zugriff auf ihre Elemente zulassen. Im Hintergrund läuft immer ein Suchalgorithmus in einem Hashtable ab, es sei denn, man rückt elementweise weiter. Daher kann der Zugriff mit foreach() und mehrfachem continue oder auch per next() eventuell sogar schneller sein, als per "Index". Der Index ist ja auch nicht echt und hat nichts mit der Position des Elementes zu tun. Sein Wert wird dem Element als Eigenschaft eingeprägt. Das Element kann aber liegen, wo es will.

              dann ist foreach nicht mehr das Mittel der Wahl. Wenn ich ab Position 7 beginnen muss, ist es unschick, im foreach erstmal bis 7 zu zählen und den Schleifenrumpf mit continue zu umgehen. Analog zu LinQ in C# könnte man sich Iteratoren bauen, die Arrayelemente überspringen können, aber das würde hier im Thread nur zur finalen Verwirrung des OP führen 😂

              Schau dir mal Sensordaten an. Das ist nur eine experimentelle Seite, die Du per Redirection und Portweiterleitung erreichst. Sie liegt auf einem Raspberry 3+. Es werden alle Daten von Anfang an in ein Array geholt, aus dem dann per foreach() und continue der passende Ausschnitt ausgelesen wird. Wie man sieht, geht das immer noch so schnell, dass man nicht daran denkt, dass da ein paar Tausend Mal (Stand heute ca. 31.100 Mal) continue benutzt wird, bevor die Anzeige gebaut werden kann.

              Man sollte also seine Angst verlieren vor derartigen Konstrukten. Nur weil ich selber zu faul wäre, zuerst mehrere Tausend Karteikarten zu lesen, bevor ich die richtige finde, fältt das dem Computer gar nicht schwer :-)

              Glück Auf
              Tom vom Berg

              --
              Es gibt nichts Gutes, außer man tut es!
              Das Leben selbst ist der Sinn.
            2. Hallo Zusammen und Danke nochmals

              Versuche es nochmals zu erklären.

              Wenn ich die höchste Zahl von "oben" (40) habe, muss dann die Zahl "unten" (20) von der höchsten Zahl "oben" (40) mindestens einmal unterschritten werden.

              Das passiert mit der Zahl "unten" (15).

              Dann wenn es wieder eine höchste Zahl "oben" (45) gibt, habe ich somit ein treffer (zahl markieren).

              Danach wieder von vorne, von der höchsten Zahl "oben" (45) muss jetzt auch wieder zuerst die Zahl "unten" (22) mindestens einmal unterschritten werden

              und dann eine neue höchste Zahl, damit ich wieder einen treffer bekommen kann.


              Deshalb brauche ich nicht einfach die höchste Zahl und die tiefste Zahl vom Array. Es muss der Reihe nach gehen

              Miky

              1. Hallo Miky,

                Versuche es nochmals zu erklären.

                Verständlicher wäre zu erläutern, was du mit deinem gewünschten Resultat beabsichtigst.

                Deshalb brauche ich nicht einfach die höchste Zahl und die tiefste Zahl vom Array.

                Da wurde dir schon min() und Max() genannt.

                Es muss der Reihe nach gehen

                Das ist wieder nicht, für mich zumindest, zu verstehen warum das so sein muss.

                Gruss
                Henry

                --
                Meine Meinung zu DSGVO & Co:
                „Principiis obsta. Sero medicina parata, cum mala per longas convaluere moras.“
                1. Deshalb brauche ich nicht einfach die höchste Zahl und die tiefste Zahl vom Array.

                  Da wurde dir schon min() und Max() genannt.

                  ups... sry hatte das "nicht" nicht gesehen.

                  Gruss
                  Henry

                  --
                  Meine Meinung zu DSGVO & Co:
                  „Principiis obsta. Sero medicina parata, cum mala per longas convaluere moras.“
              2. Hallo,

                Ok.
                Du brauchst entweder ein Ergebnis-Array oder musst im Ausgangs-Array eine Ergebnis-Eigenschaft mitführen.

                Außerdem brauchst einen Merker, ein sogenanntes flag, mit dem entschieden wird, ob grad die obere oder untere Zahl relevant ist.

                Gruß
                Kalk

              3. Liebe Mitdenker, liebe Wissende, liebe Neugierige,

                Versuche es nochmals zu erklären.

                Wenn ich die höchste Zahl von "oben" (40) habe, muss dann die Zahl "unten" (20) von der höchsten Zahl "oben" (40) mindestens einmal unterschritten werden.

                Das passiert mit der Zahl "unten" (15).

                Dann wenn es wieder eine höchste Zahl "oben" (45) gibt, habe ich somit ein treffer (zahl markieren).

                Danach wieder von vorne, von der höchsten Zahl "oben" (45) muss jetzt auch wieder zuerst die Zahl "unten" (22) mindestens einmal unterschritten werden

                und dann eine neue höchste Zahl, damit ich wieder einen treffer bekommen kann.


                Deshalb brauche ich nicht einfach die höchste Zahl und die tiefste Zahl vom Array. Es muss der Reihe nach gehen

                Mir scheint, dass er relative Minima und relative Maxima einer Kurve bzw. Wertepaarmenge sucht.

                Wieso die Werte paarig auftreten, habe ich aber auch noch nicht verstanden.

                Spirituelle Grüße
                Euer Robert

                --
                Möge der Forumsgeist ewig leben!
              4. Hallo Miky,

                ah, ein par neue Würmer sind aus der Nase hervorgekrochen.

                • Es muss ein hin- und her sein
                • Es gibt mehr als einen Treffer
                • Die Treffer müssen markiert werden

                Dir ist das vermutlich alles selbstverständlich, aber Du erklärst uns nicht, wo du herkommst und wo du hinwillst, und darum ist das für uns nur Rätsel raten. Dir kann keiner helfen, wenn Du uns nicht deine Aufgabenstellung vollständig beschreibst. Zur Zeit habe ich noch einige mögliche Varianten im Kopf, die aber sehr verschieden sind und die von Details deiner Problemstellung abhängen.

                Ich versuche nochmal eine eigene Fassung, vielleicht kommen wir damit zu einer systematischen Darstellung. Ich halte mich ganz bewusst von konkretem PHP fern.

                Wir haben eine Liste von N Zahlenpaaren, besteht aus einem "unten" und einem "oben" Wert. Startpunkt ist der erste Eintrag in der Liste.

                Nun wird abwechselnd eine "oben" und eine "unten" Suche ausgeführt. Es beginnt mit einer "oben" Suche, Vergleichswert ist der "oben" Wert im Listeneintrag. Gesucht wird ab dem zweiten Listeneintrag.

                Wiederhole die beiden folgenden Schritte, bis Du am Ende der Liste bist:

                • Suche "oben", bis die Liste zu Ende ist oder ein Eintrag gefunden wird, dessen "oben" Wert größer als der "oben" Vergleichswert ist. Dies ist ein "oben" Treffer, sein "unten" Wert wird zum neuen "unten" Vergleichswert und die Suche geht auf dem Folgeeintrag der Liste weiter.
                • Suche "unten", bis die Liste zu Ende ist oder ein Eintrag gefunden wird, dessen "unten" Wert kleiner als der "unten" Vergleichswert ist. Der "oben" Wert dieses Eintrags wird zum neuen "oben" Vergleichswert und die Suche geht auf dem Folgeeintrag der Liste weiter.*

                Wäre dieses Vorgehen das, was Du Dir vorstellst? Wenn ja, könnte man über Code sprechen. Die Frage, wie Treffer gespeichert oder markiert werden, wäre dann als nächstes zu behandeln.

                Rolf

                --
                sumpsi - posui - clusi
              5. Schreib doch den Algorithmus mal auf. Dann dürfte es auch kein Problem sein den nach PHP umzusetzen. MFG

      2. Tipp: Du möchtest Dir das Ergebnis bzw. die Zahl zwischenspeichern die beim letzten Vergleich (größer oder kleiner als..) gewonnen hat. MFG

      3. Liebe(r) Miky,

        Du willst also die größte "oben"-Zahl und die kleinste "unten"-Zahl haben. Oder ist das nicht richtig?

        Liebe Grüße

        Felix Riesterer

        1. Hallo Felix,

          Du willst also die größte "oben"-Zahl und die kleinste "unten"-Zahl haben. Oder ist das nicht richtig?

          Ich vermute, keiner hier weiss so richtig, was er eigentlich vorhat. Könnte es sein, dass sich seine Aufgabe grösstenteils mathematisch lösen lässt, anstatt alles zu durchlaufen? Bin leider kein Matheprofi, wie so manch anderer hier, aber neugierig genug das zu fragen.

          Gruss
          Henry

          --
          Meine Meinung zu DSGVO & Co:
          „Principiis obsta. Sero medicina parata, cum mala per longas convaluere moras.“
  3. Bedenke, daß es zu einem if nur ein else geben kann. Wenn Du eine Kontrollstruktur jedoch erweitern willst, brauchst Du elsif. MFG

  4. Liebe(r) Miky,

    ist denn in den Wertepaaren unten immer niedriger als oben?
    Mir scheint, dass Du immer das relative Minimum zwischen zwei relativen Maxima suchst. Stimmt das?

    Da könnte man ja glatt die Min/Max-Werte von Toms Wetterdaten als Beispiel nehmen. Kennzeichne Dir in der Liste mal die relativen Maxima und such dann dazwischen die relativen Minima. Ist es das, was Du willst?

    Spirituelle Grüße
    Euer Robert

    --
    Möge der Forumsgeist ewig leben!