Marco: Suche in einem Mehrdimensionalem Array

Moinsen,

die Suche in einem Mehrdimensionalem Array :)
Die Datenbank wird abgefragt, die Daten werden in einem Mehrdimensionalem Array gespeichert.

Array Aufbau:

Array  
(  
    [0] => Array  
        (  
            [0] => TEST    //Name  
            [1] => 12430   //ID  
            [2] => Y       //Save  
            [3] => -101    //Wert  
        )  
  
    [1] => Array  
        (  
            [0] => TEST    //Name  
            [1] => 12710   //ID  
            [2] => Y       //Save  
            [3] => -99     //Wert  
        )  
...

Der Wert "Y" ändert sich ständig. Ich muss den Wert "Y" mit der "ID" überprüfen.
Wie schaffe ich das?

Mit der Datenbank wäre das kein Problem:

SELECT save FROM tabelle_test WHERE id = 12430

So könnte ich jeden Datensatz einzelnt abfragen.
Bei ca. 2000 Datensätzen, wollte ich das lieber mit einem Array machen :)

Wie würdet ihr da vorgehen? Anregungen? Tipps?

Vielen Dank

MfG
Marco

  1. Moin Marco,

    inwiefern ändert sich der Wert SAVE=Y ständig? Ändert er sich in der Datenbank, so ändert er sich ja aktuell nicht in Deinem Array. Und bei jeder Ausführung des Scripts alle Datensätze in ein Array zu laden ist sicherlich auch nicht sonderlich performant.
    Wäre es nicht ausreichend, lediglich diejenigen Sätze aus der DB in ein ARRAY zu selektieren, die SAVE=Y gesetzt haben?
    SELECT id FROM tabelle_test WHERE Save='Y'

    Benötigst Du hingegen alle Datensätze, dann lade sie Dir alle in ein ARRAY, ggf. sogar ein nammed Array, welches nicht von 0-... durchgezählt wird, sondern in dem der Array-Key die ID ist:

    Array  
    (  
       [12430] => Array  
               (  
                  [Name] => TEST  
                  [Save] => Y  
                  [Wert] => -101  
               )  
       [12431] => Array  
               (  
                  [Name] => TEST2  
                  [Save] => Y  
                  [Wert] => -12  
               )  
    ...
    

    Du könntest Dir dann in Deinem Script ein weiteres Array aufbauen, welches lediglich diejenigen Datensätze vermerkt, welche SAVE=Y gesetzt haben. Der Wert in dem Array spiegelt die ID in dem ersten Array wieder:

    Array  
    (  
       [0] => 12430  
       [1] => 12431  
    ...
    

    Ich vermute mal, Du benötigst für die Aktuelle Ausführung lediglich die Datensätze, die SAVE=Y gestezt haben. Somit wäre es am sinnvollsten dies direkt mittels SQL-Statement zu ermitteln.

    Viele Grüße,
    the-FoX

    1. Hello the-FoX,

      Benötigst Du hingegen alle Datensätze, dann lade sie Dir alle in ein ARRAY, ggf. sogar ein nammed Array, welches nicht von 0-... durchgezählt wird, sondern in dem der Array-Key die ID ist:

      Array

      (
         [12430] => Array
                 (
                    [Name] => TEST
                    [Save] => Y
                    [Wert] => -101
                 )
         [12431] => Array
                 (
                    [Name] => TEST2
                    [Save] => Y
                    [Wert] => -12
                 )
      ...

        
        
      Und wenn man das gleich anders herum aufbaut, kann man sogar nach jeder Spalte sortieren mit den Standard-Array-Funktionen von PHP und das sogar parallel nebeneinander und auch für Summe, Produkt, usw. die Standard-Array-Funktionen nutzen!  
        
        
      ~~~php
        
        
      Array  
      (  
          [Name][12430] => TEST  
          [Save][12430] => Y  
          [Wert][12430] => -101  
        
          [Name][12431] => TEST2  
          [Save][12431] => Y  
          [Wert][12431] => -12  
      )  
      
      

      siehe: https://forum.selfhtml.org/?t=217052&m=1490044

      Liebe Grüße aus dem schönen Oberharz

      Tom vom Berg

      --
       ☻_
      /▌
      / \ Nur selber lernen macht schlau
      http://bikers-lodge.com
    2. Moinsen,

      inwiefern ändert sich der Wert SAVE=Y ständig? Ändert er sich in der Datenbank, so ändert er sich ja aktuell nicht in Deinem Array. Und bei jeder Ausführung des Scripts alle Datensätze in ein Array zu laden ist sicherlich auch nicht sonderlich performant.

      Ich erhalte die Daten von einer XML Datei, diese Daten ändern sich ständig. Entweder ist der Wert "Y" oder "N"...
      Da ich mein Script mit einem Cron ausführe, denke ich das es besser wäre, wenn PHP das ganze verarbeitet. Oder meint ihr es ist besser, es der Datenbank zu überlassen?
      Das Script wird alle 15 Min aktualisiert * 2000 Daten.
      Das war aber noch nicht alles. Da kommen insgesamt noch 4000 Daten dazu :D
      Wären also 6000 Daten alle 15 Min. Das kann ich doch nicht der Datenbank überlassen?!

      Benötigst Du hingegen alle Datensätze, dann lade sie Dir alle in ein ARRAY, ggf. sogar ein nammed Array, welches nicht von 0-... durchgezählt wird, sondern in dem der Array-Key die ID ist:

      Array

      (
         [12430] => Array
                 (
                    [Name] => TEST
                    [Save] => Y
                    [Wert] => -101
                 )
         [12431] => Array
                 (
                    [Name] => TEST2
                    [Save] => Y
                    [Wert] => -12
                 )
      ...

        
      Genau so hatte ich mir das vorgestellt, perfekt :)  
        
      
      > Ich vermute mal, Du benötigst für die Aktuelle Ausführung lediglich die Datensätze, die SAVE=Y gestezt haben. Somit wäre es am sinnvollsten dies direkt mittels SQL-Statement zu ermitteln.  
        
      Leider brauche ich alle Werte die ich angegeben habe. Somit spare ich nochmals Datenbankabfragen.  
        
      Vielen Dank für deine Anregungen, Tipps etc. :)  
        
      MfG  
      Marco
      
  2. Tach!

    die Suche in einem Mehrdimensionalem Array :)

    Wenn du genau hinschaust, hast du ein Array vorliegen, dessen Elemente Arrays sind.

    Der Wert "Y" ändert sich ständig. Ich muss den Wert "Y" mit der "ID" überprüfen.
    Wie schaffe ich das?

    Durchlauf das Array und schau dir die Elemente an, also die inneren Arrays.

    Wie würdet ihr da vorgehen? Anregungen? Tipps?

    Man kann da auch funktional an die Lösung gehen, indem man die vorhandenen Array-Funktionen nimmt, die da mit array_ anfangen und auf walk, map und reduce enden, je nachdem, was man erreichen will. Allen dreien gemeinsam ist, dass man ihnen ein Callback (zum Beispiel eine anonyme Funktion) übergeben kann, das jeweils ein Element in Bezug auf das gewünschte Ergebnis untersucht.

    So zumindest einige Möglichkeiten, wenn die Daten bereits abgefragt sind. Das DBMS kann da auch schon in Vorfeld filtern, wenn das für deinen Anwendungsfall praktikabel ist.

    dedlfix.

  3. Hello,

    die Suche in einem Mehrdimensionalem Array :)
    Die Datenbank wird abgefragt, die Daten werden in einem Mehrdimensionalem Array gespeichert.

    Array Aufbau:

    Array

    (
        [0] => Array
            (
                [0] => TEST    //Name
                [1] => 12430   //ID
                [2] => Y       //Save
                [3] => -101    //Wert
            )

    [1] => Array
            (
                [0] => TEST    //Name
                [1] => 12710   //ID
                [2] => Y       //Save
                [3] => -99     //Wert
            )
    ...

    
    >   
    > Der Wert "Y" ändert sich ständig. Ich muss den Wert "Y" mit der "ID" überprüfen.  
    > Wie schaffe ich das?  
      
    Nimm einen anderen Array-Aufbau. Es ist durchaus erlaubt, quer zu denken und sich seine Datenstrukturen so anzulegen, wie man sie benötigt:  
      
    <http://forum.de.selfhtml.org/archiv/2009/5/t187244/#m1244374>  
      
    Dann würde dein Array in etwa so aussehen:  
      
    ~~~php
      
    $_data['name'][0] = 'TEST'  
    $_data['name'][1] = 'TEST'  
    ...  
    $_data['id'][0]   = 12430  
    $_data['id'][1]   = 12710  
    ...  
    $_data['save'][0]   = 'Y'  
    $_data['save'][1]   = 'Y'  
    ...  
    $_data['wert'][0]   = -101  
    $_data['save'][1]   = -99  
    
    

    BTW: es bietet sich an, bezeichner z.B. immer klein zu schreiben und nicht mal gemein, mal versal, mal in Höckerschreibweise (camelCase),

    Die benötigrten Funktionen für das Array in Spaltenschreibweise sind:

    $recno ist die Unique-Datensatz-ID

      
    #------------------------------------------------------------------------------  
    function get_record (&$_data, $recno)  
    {  
        $_rec = array();  
      
        foreach ($_data as $colname => $field)  
        {  
            $_rec[$colname] = isset($_data[$colname][$recno])?$_data[$colname][$recno]:NULL;  
        }  
      
        return $_rec;  
    }  
    #------------------------------------------------------------------------------  
    
    
      
    #------------------------------------------------------------------------------  
    function delete_record (&$_data, $recno)  
    {  
        $cols_deleted = 0;  
      
        foreach ($_data as $colname => $field)  
        {  
            unset($_data[$colname][$recno]);  
            $cols_deleted++;  
        }  
      
        return $cols_deleted;  
    }  
    #------------------------------------------------------------------------------  
    
    
      
    #------------------------------------------------------------------------------  
    function update_record(&$_data, $recno, $_record, $expand=false)  
    {  
        $cols_updated = 0;  
      
        foreach ($_record as $colname => $data)  
        {  
            if ($expand or isset($_data[$colname][$recno]))  
            {  
                $_data[$colname][$recno] = $data;  
                $cols_updated++;  
            }  
        }  
      
        return $cols_updated;  
    }  
    #------------------------------------------------------------------------------  
    
    
      
    #------------------------------------------------------------------------------  
    function insert_record(&$_data, $recno, $_record, $expand=false, $overwrite=false)  
    {  
        $cols_inserted = 0;  
      
        if (!$overwrite)  
        {  
            foreach($_record as $colname => $data)  
            {  
                if (isset($_data[$colname][$recno]))  
                {  
                    return 0;  
                }  
            }  
        }  
      
        foreach ($_record as $colname => $data)  
        {  
            if ($expand or isset($_data[$colname]))  
            {  
                $_data[$colname][$recno] = $data;  
                $cols_inserted++;  
            }  
        }  
      
        return $cols_inserted;  
    }  
    #------------------------------------------------------------------------------  
    
    

    Die Funktionen sind universell. Du kannst sie also benutzen, ohne nochmal Hand anlegen zu müssen.

    Außerdem bietet es sich an, sofort die Unique-ID aus der DB auch als Index im Array zu benutzen:

    dann würde dein Array in etwa so aussehen:

      
    $_data['name'][12430] = 'TEST'  
    $_data['name'][12710] = 'TEST'  
    ...  
    $_data['save'][12430]   = 'Y'  
    $_data['save'][12710]   = 'Y'  
    ...  
    $_data['wert'][12430]   = -101  
    $_data['save'][12710]   = -99  
    
    

    Über den Index kann man seine Spalten nun im Direktzugriff vergleichen und muss nicth erst suchen.

    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Und sollte mal wieder der Spruch kommen: "Datenstrukturen soll man aber zusammenhalten" dann hier bereits meine Erwiderung: Die Daten stehen doch zusammen (im Speicher)! Und was meint Ihr denn, wie die Datenbank das intern organisiert?
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Viel Spaß damit

    und

    liebe Grüße aus dem schönen Oberharz

    Tom vom Berg

    --
     ☻_
    /▌
    / \ Nur selber lernen macht schlau
    http://bikers-lodge.com
    1. Moinsen,

      also ähm... Wahnsinn !!! :D

      Vielen Dank für dein Wahnsinns Beispiel. Die Funktionen sind sehr umfangreich, werde ich sicherlich nochmal gebrauchen können.

      Das ist aber sehr sehr sehr komplex für mein Vorhaben.

      Ich denke für mein Vorhaben langt ein einfaches:

      $array[$row['id']] = $row;

      Somit kann ich die Arrays mit der ID ansprechen.

      PS: Ich schreibe die Spaltennamen immer "klein" war auch nur als Hilfe, beispiel gedacht ;)

      Vielen Dank

      MfG
      Marco

      1. Hello,

        Vielen Dank für dein Wahnsinns Beispiel. Die Funktionen sind sehr umfangreich, werde ich sicherlich nochmal gebrauchen können.

        Das ist nicht Wahnsinn, sondern praktisch. Die andere Notation für Datensätze in PHP-Arrays (die für uns Anwender ja eigentlich verkettete Listen sind, also Baumstrukturen // innen gehört noch mehr dazu) als "Spaltenarray" ermöglicht einem die reichlich vorhandenen einfachen Array-Funktionen zu benutzen. Die sind wesentlich verständlicher, als diejenigen mit "Back-*"

        Da kan man sich dann schon mal damit abfinden, dass man für die vier Grundfunktionen

        • Insert
        • Select
        • Update
        • Delete
          eben einen Wrapper benötigt, um die Daten aus der -Haltung wieder in die -Visualisierung zu transformieren und umgekehrt.

        Wenn Du aber schon so weit ins Messer gelaufen bist, dass die Daten als XML-Datei ankommen, kann ich Dir leider nicht mehr helfen. Das Format ist für mich ein rein theoretisches. Es wird leider auch oft benutzt.

        Da war dBase besser, kompakter, schneller!

        Bei Umwandlung von dBase-Format in "Spaltenarrays" und umgekehrt stehe ich zur Verfügung
        Bei Umwandlung von SDF (CSV) in "Spaltenarrays" und umgekehrt stehe ich zur Verfügung
        Bei Umwandlung von "Seperated Format & Data"-Format (Direct Access) sowieso (siehe meine exemplarische Anwendung unter
        http://selfhtml.bitworks.de/artikel_locking/adressen.php
        http://selfhtml.bitworks.de/artikel_locking/adressen.php.txt

        oder bei Umwandlung von Datanorm in "Spaltenarrays" und umgekehrt
        https://de.wikipedia.org/wiki/Datanorm

        XML ist im Prinzip nur ein "Datanorm + HTML-Gedanken + ungünstige Datenhaltung + viel verschwendeter Platz + Funktionen + ???". Der ursprünglich gedachte Nutzen "Human redable" ist für mich dabeio verloren gegangen.

        Denn welcher normale Mensch kann das noch lesen? Man ist über das Ziel hinaus geschossen!

        Aber was soll's? UTF-8 kann ohne Maschine sowieso niemand mehr entschlüsseln in 100 Jahren. Die außerirdischen sind unter uns *gg*

        Die Funktionen solltest Du nutzen, wie Blackboxes :-)

        Das ist aber sehr sehr sehr komplex für mein Vorhaben.

        Überhaupt nicht, wenn Du nicht schon ins Messer gelaufen bist.

        Liebe Grüße aus dem schönen Oberharz

        Tom vom Berg

        --
         ☻_
        /▌
        / \ Nur selber lernen macht schlau
        http://bikers-lodge.com
      2. Meine Herren!

        Das ist aber sehr sehr sehr komplex für mein Vorhaben.

        Das ist zu komplex für fast jedes Vorhaben.

        Die Pendants für ein übliches Zeilen-Array sehen übrigens so aus:

        $spalte = get_record( $spaltenArray, 42 );  
        $zeile = $zeilenArray[ 42 ];  
          
        update_record( $spaltenArray, 42, $geänderteSpalte );  
        $zeilenArray[ 42 ] = $geänderteZeile;  
          
        delete_record( $spaltenArray, 42 );  
        unset( $zeilenArray[ 42 ] );  
          
        insert_record( $spaltenArray, 43, $neueSpalte );  
        $zeilenArray[] = $neueZeile;
        

        Ich finde diese Operationen auf Zeilen-Arrays deutlich attraktiver.

        Es gibt weitere Nachteile:
        Sie sind inkompatibel zu objekt-orientierten Entwürfen:

        $zeilenArray[] = new Auto();  
        foreach( $zeilenArray as $auto ){  
           $auto->gibGas();  
        }  
          
        $spaltenArray???
        

        Sie sind im Gegensatz zu Toms Behauptungen schwerer zu sortieren:
        Angenommen ich habe ein Zeilenarray von Produkten vorliegen, die ich nach ihren Preis sortieren möchte, das würde ich so machen:

        usort( $zeilenArray, function( $a, $b ) {  
           if ( $a['preis'] <= $b['preis'] ){  
              return -1;  
           } else {  
              return 1;  
           }  
        });
        

        Keine Ahnung, wie man das ähnlich expressiv mit einem Spalten-Array anstellen sollte. Vielleicht kann Tom uns ja was zeigen. Machen wir die Aufgabe zum Spaß noch ein weniger schwieriger: Jedes Produkt hat einen Preis und Versandkosten, wir wollen nun nach dem Gesamt-Preis sortieren:

        usort( $zeilenArray, function( $a, $b ) {  
           if ( $a['preis'] + $a['versandkosten'] <= $b['preis'] + $b['versandkosten'] ) {  
              return -1;  
           } else {  
              return 1;  
           }  
        }
        

        Ich sehe keinen Vorteil in der Verwendung von Spalten-Arrays, jede noch so einfache Operation auf den Daten wird vollkommen unnötiger Weise verkompliziert. Ich bemerke hier nur einen schlechten Entwurf.

        --
        “All right, then, I'll go to hell.” – Huck Finn
        1. Hello,

          Sie sind im Gegensatz zu Toms Behauptungen schwerer zu sortieren:
          Angenommen ich habe ein Zeilenarray von Produkten vorliegen, die ich nach ihren Preis sortieren möchte, das würde ich so machen:

          usort( $zeilenArray, function( $a, $b ) {

          if ( $a['preis'] <= $b['preis'] ){
                return -1;
             } else {
                return 1;
             }
          });

            
            
          
          >   
          > Keine Ahnung, wie man das ähnlich expressiv mit einem Spalten-Array anstellen sollte. Vielleicht kann Tom uns ja was zeigen. Machen wir die Aufgabe zum Spaß noch ein weniger schwieriger: Jedes Produkt hat einen Preis und Versandkosten, wir wollen nun nach dem Gesamt-Preis sortieren:  
            
            
          ~~~php
            
          ksort($_data['preis'],SORT_NUMERIC);  
            
          #und zur Ausgabe einer Liste dann über die sortierte Spalte iterieren mit der Select-Funktion  
            
          foreach($_data['preis'] as $key => $value  
          {  
              ausgabe(get_record($_data, $key);  
          }  
            
          # Ausgabe muss man sich immer selber schreiben, egal in welcher Form die Daten vorliegen  
            
          
          

          Ich sehe keinen Vorteil in der Verwendung von Spalten-Arrays, jede noch so einfache Operation auf den Daten wird vollkommen unnötiger Weise verkompliziert. Ich bemerke hier nur einen schlechten Entwurf.

          *tztz*

          Liebe Grüße aus dem schönen Oberharz

          Tom vom Berg

          --
           ☻_
          /▌
          / \ Nur selber lernen macht schlau
          http://bikers-lodge.com
          1. Meine Herren!

            ksort($_data['preis'],SORT_NUMERIC);

            #und zur Ausgabe einer Liste dann über die sortierte Spalte iterieren mit der Select-Funktion

            foreach($_data['preis'] as $key => $value
            {
                ausgabe(get_record($_data, $key);
            }

              
            Du wolltest asort anstatt ksort schreiben – dann geht die Logik auf. Gut nach einer Spalte sortieren ist damit abgehandelt. Kompliziertere Sortier-Kriterien, wie in dem leicht modifizierten Beispiel, halte ich weiterhin für problematisch. Man könnte wohl eine temporäre Zeile anlegen, die die Summe des Warenpreises und der Versandkosten enthält, und dann danach sortieren. Finde ich persönlich unnötig umständlich. Sortieren nach Nachname und als zweites Kriterium nach Vorname halte ich für einen weiteren Problemfall, der mit Zeilen-Arrays einfacherer gelöst wäre.  
              
            Das Sortieren ist nur ein Beispiel für eine Alltags-Aufgabe, in der mir Spalten-Arrays nur in die Quere kommen, Filtern, Mappen, Reduzieren sind weitere.  
              
            
            > \*tztz\*  
              
            Du kannst sie ja gerne weiter benutzen. Ich werde sie weiterhin meiden. Wenn du sie empfiehlst, werde ich eben davor warnen. Die Debatte steht und jeder kann für sich selber entscheiden, ob er daraus einen Nutzen ziehen kann oder Lasten tragen muss.  
            
            -- 
            “All right, then, I'll go to hell.” – Huck Finn
            
            1. Hello,

              ksort($_data['preis'],SORT_NUMERIC);

              #und zur Ausgabe einer Liste dann über die sortierte Spalte iterieren mit der Select-Funktion

              foreach($_data['preis'] as $key => $value
              {
                  ausgabe(get_record($_data, $key);
              }

              
              >   
              > Du wolltest asort anstatt ksort schreiben – dann geht die Logik auf.  
                
              Nein. Geh nach Haus und üb erstmal :-P  
                
                
                
              Liebe Grüße aus dem schönen Oberharz  
                
                
              Tom vom Berg  
              ![](http://selfhtml.bitworks.de/Virencheck.gif)  
                
              
              -- 
               ☻\_  
              /▌  
              / \ Nur selber lernen macht schlau  
              <http://bikers-lodge.com>
              
              1. Meine Herren!

                Du wolltest asort anstatt ksort schreiben – dann geht die Logik auf.

                Nein. Geh nach Haus und üb erstmal :-P

                Äh? ksort Sortiert ein Array anhand der Schlüssel und erhält dabei die Assoziationen von Schlüssel und Wert. asort sortiert anhand des Wertes und erhält ebenfalls die Assoziationen zu den Schlüsseln.

                $produkte = array(  
                   'name' => array( 0 => 'Toast',  1 => 'Roggenbrötchen'),  
                   'preis' => array( 0 => 1.25, 1 => 0.39)  
                );  
                  
                ksort( $produkte['preis'], SORT_NUMERIC );  
                  
                foreach($produkte['preis'] as $key => $value)  
                {  
                   $record = get_record($produkte, $key);  
                   print_r( $record );  
                }
                

                Ergibt:

                Array  
                (  
                    [name] => Toast  
                    [preis] => 1.25  
                )  
                Array  
                (  
                    [name] => Roggenbrötchen  
                    [preis] => 0.39  
                )
                

                Die Variante mit asort dagegen:

                Array  
                (  
                    [name] => Roggenbrötchen  
                    [preis] => 0.39  
                )  
                Array  
                (  
                    [name] => Toast  
                    [preis] => 1.25  
                )
                

                Es sei dir vergeben, Spalten-Arrays sind eben schwierig zu handhaben ;)

                --
                “All right, then, I'll go to hell.” – Huck Finn
                1. Hello,

                  Du wolltest asort anstatt ksort schreiben – dann geht die Logik auf.

                  Ok, Du hat Recht. "Blamiere dich täglich" passt mal wieder.
                  Da geh ich jetzt nochmal üben :-)

                  Dabei habe ich es mir vorhin extra nochmal auf den Schirm geholt.
                  Es sollten ja nicht die Schlüssel sortiert werden, sondern die Elemente unter Beibehaltung der Schlüssel.

                  Ich hatte die Beschreibung von "sort()" auf dem Schirm, was ja nun eindeutig die falsche Wahl ist. Ich bin mir aber ganz sicher, dass ich auf asort links im Menu geklickt hatte. sort() steht ja viel tiefer. Und bei ksort hatte ich dann die Beschreibung von asort(). Merkwürdig. Kommt das Online-Manual irgendwie aus einer Datenbank? Die basteln da ja scheinbar sowieso gerade dran herum.

                  Liebe Grüße aus dem schönen Oberharz

                  Tom vom Berg

                  --
                   ☻_
                  /▌
                  / \ Nur selber lernen macht schlau
                  http://bikers-lodge.com