Ankündigung

Einklappen
Keine Ankündigung bisher.

[Erledigt] Multidimensionales Array - Zugriff über die Werte eines anderen Arrays

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • [Erledigt] Multidimensionales Array - Zugriff über die Werte eines anderen Arrays

    Guten Morgen,
    ich hab eine Mutlidimensionales Array (ab jetzt MDA) und möchte mit einem zweiten Array("Steuer Array", ab jetzt SA), genauer gesagt mit dessen Werte (in logischer Rheinfolge(0,1,2,...n), auf das erste Array zugreifen.

    Also ca. so:
    PHP-Code:
    $mda[$sa[0]][$sa[1]][$sa[2]] ..... [$sa[n]] 
    Ich habe das ganze bereits Iterativ und Rekursiv ohne Probleme umgesetzt... meine Frage ist: gibts das irgentwie schon als "native" Funktion? Hab sowas noch nicht gefunden.

    Sieht so aus:
    PHP-Code:
    function searchArrayForPathIterative($mda$path) {
        
    $pathIndex 0;
        
    $tmp $mda;
        
        while(
    $pathIndex count($path)) {
            if(empty(
    $tmp[$path[$pathIndex]])) {
                return 
    null;
            }
            
    $tmp $tmp[$path[$pathIndex]];
            
    $pathIndex++;
        }
        return 
    $tmp;

    Nachtrag: Es geht hierbei um Performanz, diese Funktion wird relativ häufig verwendet, deswegen ziehe ich hier erstmal die Iterative der Rekursiven (bzw. dem "bösen" eval() Konstrukt) vor. Falls es sowas noch nicht gibt werde ich das ganze selbst als Modul in C umsetzen (falls wer Interesse hat gebe ich dann auch den Quellcode dazu raus).

  • #2
    könntest du selbst erklären, was du bei jeder zeile damit willst?

    Kommentar


    • #3
      foreach?

      Kommentar


      • #4
        Zitat von Nightmares Beitrag anzeigen
        PHP-Code:
            while($pathIndex count($path)) { 
        Nachtrag: Es geht hierbei um Performanz, ...
        count($path) gehört nicht in den Schleifenkopf, da sich an $path nix ändert.

        Kommentar


        • #5
          Warum nicht einfach einen Iterator verwenden? http://php.net/manual/de/class.iterator.php

          Kommentar


          • #6
            a) ja stimmt, das gehört nicht in den Schleifenkopf,

            b) Code Update
            PHP-Code:
            function searchArrayForPathIterative($mda$path) {
                
            $pathIndex 0;
                
            $tmp $mda;
                
            $pathSize count($path);
                
                while(
            $pathIndex $pathSize) {
                    if(empty(
            $tmp[$path[$pathIndex]])) {
                        return 
            null;
                    }
                    
            $tmp $tmp[$path[$pathIndex]];
                    
            $pathIndex++;
                }
                
                return 
            $tmp;

            c) was mich am Iterator stört: Objekt overhead

            d) Orginal Frage: Gibts das bereits als native Methode in PHP (C ist halt schneller als PHP), ich brauch die Methode leider sehr oft und kann auch die Datenstruktur nicht ändern (schlechte API, habe ich leider die wahl nicht).

            Die Iterative Variante is ja schonmal erheblich schneller als die Rekursive. Allerdings halt nicht das gelbe vom Ei. Das ganze mal in C umgesetzt ist bei den gleichen Testarrays einfach bedeutend schneller (wenn man nur den Pointer durch das Array bewegt und nicht immer eine Array Kopie (eines Ausschnittes) anlegen muss wie in der Zeile:
            PHP-Code:
            $tmp $tmp[$path[$pathIndex]]; 
            Das gleiche gilt für den Iterator: Objekt Overhead...

            Wirklich keiner eine Idee obs sowas schon gibt?

            EDIT:
            bzw in C: map<string,string> usw.

            Kommentar


            • #7
              ich verstehe nicht was du mit diese code ergreifen willst...
              ...
              Du willst prüffen ob es im associativen array $mda sonst eine key-name gibt die von namen im array $path zur verfügung steht. Du beginst whilen und wenn sonst eine name von $path in $mda[key] nicht gibt dann returnst du sofort mit null raus. Aber wenn es gibt $mda[key-name von $path[n]] dann überschreibst du bei jedem treffer $tmp mit gleichem verzeichnis ($mda[key-name])... Willst du beim ersten treffer die suche nicht abbrechen und $tmp genießen? Oder willst du unbedingt ganze $path uberpruffen um sicher zu sein dass dort keine value gibt die im $mda als key-name nicht gibt? Wenn ja, dann bei erster fehlschlage bekommst du wieder nur ein NULL.............................................. ........

              Kommentar


              • #8
                Also implementiert wird es das nicht geben in PHP.
                Wenn ich Dein Vorhaben richtig verstanden habe, könnte man evtl. auf sowas aufbauen:
                PHP-Code:
                function getSALevelFromMDA$keys$src, &$result ) {
                  
                $result $src;

                  if( 
                count($keys)>) {
                    
                getSALevelFromMDAarray_values(array_slice($keys1)), $src[$keys[0]], $result );
                  }
                }

                getSALevelFromMDA$sa$mda$result ); 

                Kommentar


                • #9
                  Was du gemacht hast war einfach die rekursive Lösung. Das ist deutlich langsamer als Iterativ. Allerdings hast du mir eine Idee geben, mit der das ganze noch nen Tick schneller geht:
                  PHP-Code:
                  function searchArrayForPathIterative($mda$path) {
                      
                  $pathIndex 0;
                  // tmp wird zum alias für $mda
                      
                  $tmp = &$mda;
                      
                  $pathSize count($path);
                      
                      while(
                  $pathIndex $pathSize) {
                          if(empty(
                  $tmp[$path[$pathIndex]])) {
                              return 
                  null;
                          }
                  // $tmp wird zum alias von einem teil von $tmp
                          
                  $tmp = &$tmp[$path[$pathIndex]];
                          
                  $pathIndex++;
                      }
                      
                      return 
                  $tmp;

                  Das ganze ist zwar kein "richtiger" Pointer, laut Test aber nochmal schneller und annehmbar. Ich glaube hierbei belassen wir es mal und ich makier das ganze als erledigt. Werde wohl doch irgentwan eine C Lösung Umsetzen müssen, aber die letzte Verbesserung hat nochmal ordentlich was gebracht.

                  Nachtrag:
                  @k133: Ich muss den ganzen Pfad durchlaufen (sonst wäre die ganze Aktion eh sinnlos, irgentwie muss ich am Ende ja auch an die Daten kommen oder?). Allerdings kann ich jeweils abbrechen, wenn in einer Ebene der Teil des Pfades nicht da ist.
                  Deswegen habe ich das ganze im 1. Post auch so beschrieben:
                  PHP-Code:
                   $mda[$sa[0]][$sa[1]][$sa[2]] ..... [$sa[n]] 
                  Nachtrag2:
                  Natürlich könnte ich das ganze auch als richtig großer if-Baum Umsetzen bis zur zum Beispiel 10. Ebene und von da aus dann mit der Iterativen Funktion weiter machen:
                  PHP-Code:
                  $pathSize count($path)
                  if(
                  $pathSize == 1)
                  return 
                  $mda[$path[1]]
                  elseif(
                  $pathSize == 2)
                  return 
                  $mda[$path[1]][$path[2]]
                  elseif(
                  $pathSize == n)
                  return 
                  $mda[$path[1]][$path[2]]....$mda[$path[n]]
                  else
                  return 
                  iterativeMethode($source,$path

                  Kommentar

                  Lädt...
                  X