Mathias Fiedler: Array auslesen

Ich habe ein Array wie dieses

$test       = array();
$test[0]    = array();
$test[0][0] = "1";
$test[0][1] = "abc";
$test[0][2] = "hallo";
$test[0][3] = "morgen";
$test[0][4] = "100";
$test[0][5] = "2025-10-03";

$test[1]    = array();
$test[1][0] = "3";
$test[1][1] = "abcd";
$test[1][2] = "hallo22";
$test[1][3] = "morgen";
$test[1][4] = "200";
$test[1][5] = "2025-10-03";

und so weiter

Ich möchte ganz gezielt die indexe [2], [3], [4], [5] der zweiten Ebene auslesen.

Aber nur die, wo zweite Ebene 0 = 3 und zweite Ebene 1 = abcd ist.
Der Index der ersten Ebene ergibt sich aus den Treffern der zweiten Ebene.

Den selben Effekt erreiche ich, wenn ich die erste Ebene mit einer for Schleife durchlaufe und nach [$zähler][0] = 3 AND [$zähler][1] = "abcd" suche. Aber da müsste ich die Schleife für jede Suche nach dieser Kmbi Kombination extra laufen lassen.

Ich brauche quasi so etwas wie eine Datenbankabfrage für eine Array. Geht sowas?

  1. Hallo Mathias,

    Performance optimiert man wenn man ein Problem bemerkt oder erwartet. Warum erwartest du eins? Wie oft pro Sekunde wird, über alle Requests hinweg, diese Suche ausgeführt?

    Und wie groß ist das Array, das du da durchsuchst?

    Rolf

    --
    sumpsi - posui - obstruxi
  2. Hi,

    Ich habe ein Array wie dieses

    Ich brauche quasi so etwas wie eine Datenbankabfrage für eine Array. Geht sowas?

    Warum liegen die Daten dann im Array und nicht in einer Datenbank?

    cu,
    Andreas a/k/a MudGuard

  3. Lieber Mathias,

    Ich brauche quasi so etwas wie eine Datenbankabfrage für eine Array.

    ist das so? Mir kommt es eher so vor, dass Deine Unter-Arrays in Wirklichkeit Objekte mit Eigenschaften sein möchten. Zumindest kannst Du das einigermaßen nachbilden, indem die Indizes (nicht „Indexe“, bitte!) vernünftige Bezeichner bekommen, anstatt Zahlenwerte:

    $test = [
      [
        'level' => 1,
        'name' => 'abc',
        'message' => 'hallo',
        'availabilitiy' => 'morgen',
        'amount' => 100,
        'date' => '2025-10-03'
      ],
      [
        'level' => 3,
        'name' => 'abcd',
        'message' => 'hallo22',
        'availabilitiy' => 'morgen',
        'amount' => 200,
        'date' => '2025-10-03'
      ]
    };
    

    Jetzt kannst Du die Indizes level und name gezielt auf bestimmte Werte hin untersuchen:

    $condition = [
      'level' => 3,
      'name' => 'abcd'
    ];
    
    $found = [];
    
    $wanted_properties = [
      'message' => 'Nachricht',
      'availabilitiy' => 'Verfügbarkeit',
      'amount' => 'Menge',
      'date' => 'Datum'
    ];
    
    foreach ($test as $index => $entry) {
    
      $matches = true; // erwarte passenden Eintrag
    
      foreach (array_keys($condition) as $property) {
    
        if ($entry[$property] != $condition[$property]) {
          $matches = false;
        }
      }
    
      if ($matches) {
        // In $entry steht ein gesuchter Eintrag von $test: $test[$index]
        $wanted_data = [];
    
        foreach (array_keys($wanted_properties) as $property) {
          $wanted_data[$property] = $entry[$property];
        }
    
        $found[] = $wanted_data;
      }
    }
    

    Um also zu entscheiden, ob die Arrays in $test Deinen Kriterien genügen, packst Du diese in ein Beispiel-Array $condition, um dann dessen Schlüssel-Wert-Paare mit Deinen echten Arrays zu vergleichen. Wenn alles passt, ist die Variable $matches noch immer true und Du kannst nun damit anstellen, was Du willst. Hier wird ein neues Array mit genau den Indizes gebaut, die in $wanted_properties festgelegt werden. Das so neu gebaute Array kommt in eine Trefferliste $found.

    Womit wir beim eigentlichen Thema wären: Was genau willst Du eigentlich(!) erreichen? Deine Problemstellung war eine technische, von der nicht klar ist, ob der Weg dazu überhaupt der beste für Dein Vorhaben ist. Beschreibe also gerne mehr, dann kann man Dir bessere Vorschläge machen!

    In meinem Fall sind solche Trefferlisten wie die oben erstellte nicht gut genug. Wenn es um Inhalte geht, die ich aus einer Menge an Daten filtere, will ich immer den originalen Datensatz verfügbar haben. Die oben neu erstellten Arrays sind also genau das, was ich nicht haben möchte. Lieber ist es mir, später z.B. bei der Ausgabe die für die Anzeige notwendigen Eigenschaften (hier Indices) wie im Array $wanted_properties aus dem ursprünglichen Datensatz zu verwenden:

    $found = []; // tun wir so, als ob dort Arrays von $test drin stehen
    
    foreach ($found as $entry) {
    
      foreach ($wanted_properties as $property => $display_name) {
        echo $display_name, ': ', $entry[$property];
      }
    }
    

    Liebe Grüße

    Felix Riesterer

  4. Ich brauche quasi so etwas wie eine Datenbankabfrage für eine Array.

    Was Dir als "Datenbankabfrage" vorschwebt, ist eigentlich die Nutzung eines Index', den eine Datenbank auf Anforderung anlegt (verwandt, aber nicht zu verwechseln mit dem Index eines Feldes). Ohne so einen Index, einer Art Stichwortverzeichnis, macht auch eine Datenbank lediglich das, was Dir in Form einer for-Schleife momentan Bauchschmerzen bereitet: Sie durchläuft sämtliche Datensätze.

    Sprachen (Du hast Deine nicht angegeben) bieten üblicherweise keinen Index über die Daten eines Feldes (array). Unterstützt Deine Sprache assoziative Felder, könntest Du einen Index händisch anlegen:

    for i in test:
      index[test[i][0] + "\t" + test[i][1]] = i
    

    Das Ergebnis für Dein Beispiel wäre:

    $index["1" + "\t" + "abc"] = 0;
    $index["3" + "\t" + "abcd"] = 1;
    

    Der Schlüssel besteht in diesem Beispiel aus den Werten 0 und 1 jedes Datensatzes, getrennt durch einen Tabulator (können Deine Werte auch Tabulatoren enthalten, musst Du einen anderen Trenner oder gleich eine Prüfsumme à la md5 oder sha benutzen).

    Der dazugehörige Wert ist der Index des Datensatzes in Deinem Feld $test.

    Du musst bei jeder Änderung eines Datensatzes auch den Index auf den neuesten Stand bringen (das würde eine Datenbank dir abnehmen). Womit wir dann beim Problem wären:

    Du solltest Dir im Klaren sein, dass Du Dir auf diese Weise Fehlerquellen einbaust, die ein vermeintlicher Geschwindigkeitsgewinn nicht wettmachen können wird. Falls Deine bestehende Schleife ohne nennenswerte Verzögerung läuft und Du lediglich um der Bauchschmerzen wegen optimieren möchtest, bist Du wahrscheinlich auf dem falschen Weg.

    Finde erst einmal heraus, wie sehr Deine for-Schleife Dein Programm verzögert. Dann überlege Dir, ob Du den Zugriff optimieren müsstest.

    Merke: Premature optimization is the root of all evil.