jobo: Trimmen der Werte eines zweidimensionalen Arrays

Hallo,

geht das besser?

  
<?php  
$tab[0]=array("   haaa ","xxx   ");  
$tab[1]=array("   ffhaaa ","   dddxxx   ");  
function myTrim(&$value) {  
	$value = trim($value);  
}  
array_walk_recursive($tab,"myTrim");  
var_dump($tab);  

die Werte eines zweidimensionalen Arrays zu "trimmen"?

Gruß

jobo

  1. Hallo,

    geht das besser?
    die Werte eines zweidimensionalen Arrays zu "trimmen"?

    Definiere "besser". Viel performanter dürftest Du es mit PHP wohl nicht hinkriegen, wenn Du das meinst.

    Viele Grüße,
    Christian

  2. hi,

    geht das besser?

    Iteration statt Rekursion.

    Hotti

    1. Hallo,

      Iteration statt Rekursion.

      Zwei geschachtelte foreach-Schleifen und dann die Wert kopieren?

      Gruß

      jobo

      1. Hi!

        Iteration statt Rekursion.
        Zwei geschachtelte foreach-Schleifen und dann die Wert kopieren?

        Ich halte es für fraglich, dass zwei Schleifen schneller sind als ein Funktionsaufruf und PHPs interne Abarbeitung. Letzten Endes werden die Unterschiede jedoch nicht so groß sein, dass es bei normaler Anwendung ins Gewicht fallen wird.

        Lo!

        1. Hallo,

          Iteration statt Rekursion.

          Hörte sich eher nach Refaktorisierungsprinzip an:
          http://www.refactoring.com/catalog/replaceRecursionWithIteration.html

          Man könnte es ja gleich beim Einlesen machen, aber ich kriegs bei Iteration nur mit Umkopieren hin:

            
          <?php  
          class CSV  
          {  
          	// Wird mit CSV-Daten bestückt  
          	private $_table = NULL;  
          	  
          	function __construct($filePath) {  
          		$fileHandle = @fopen($filePath,"r");  
          		if ($fileHandle) {  
          			while (($row = fgetcsv($fileHandle)) !== false) {  
          				//exclude empty lines  
          				if (!is_array($row)) {  
          					continue;  
          				}  
          				foreach ($row as $cellValue) {  
          					$trimmedRow[] = trim($cellValue);  
          				}  
          				$this->_table[] = $trimmedRow;  
          			}	  
          		}  
          		// merci handle, go free  
          		fclose($fileHandle);  
          	}	  
          	  
          	public function getTable() {  
          		if (NULL !== $this->_table) {  
          			return $this->_table;  
          		}  
          		return false;  
          	}  
          }  
          $csv = new CSV("test.csv");  
          var_dump($csv->getTable());  
          
          

          Ich halte es für fraglich, dass zwei Schleifen schneller sind als ein Funktionsaufruf und PHPs interne Abarbeitung. Letzten Endes werden die Unterschiede jedoch nicht so groß sein, dass es bei normaler Anwendung ins Gewicht fallen wird.

          Übersichtlich solls halt sein (und wartbar(;-)). Insofern find/fand ich array_walk_recursive ja eigentlich nicht so schlecht.

          Gruß

          jobo

          1. Hallo,

              
            <?php  
            class CSV  
            {  
            	// Wird mit CSV-Daten bestückt  
            	private $_table = NULL;  
            	  
            	function __construct($filePath) {  
            		$fileHandle = @fopen($filePath,"r");  
            		if ($fileHandle) {  
            			while (($row = fgetcsv($fileHandle)) !== false) {  
            				//exclude empty lines  
            				if (!is_array($row)) {  
            					continue;  
            				}  
            				foreach ($row as $cellValue) {  
            					$trimmedRow[] = trim($cellValue);  
            				}  
            				$this->_table[] = $trimmedRow;  
            			}	  
            			// merci handle, go free  
            			fclose($fileHandle);  
            		}  
            	}	  
            	  
            	public function getTable() {  
            		if (NULL !== $this->_table) {  
            			return $this->_table;  
            		}  
            		return false;  
            	}  
            }  
            $csv = new CSV("teaast.csv");  
            var_dump($csv->getTable());  
            
            

            Filehandle nur schließen, wenn Öffnen erfolgreich war.

            Gruß

            jobo

            1. Hallo,

                		foreach ($row as $cellValue) {  
                			$trimmedRow[] = trim($cellValue);  
                		}  
                		$this->\_table[] = $trimmedRow;  
              

              Schneller und kürzer:

              $this->_table[] = array_map('trim', $row);

              Viele Grüße,
              Christian

              1. Hallo,

                Hallo,

                  		foreach ($row as $cellValue) {  
                  			$trimmedRow[] = trim($cellValue);  
                  		}  
                  		$this->\_table[] = $trimmedRow;  
                

                Schneller und kürzer:

                $this->_table[] = array_map('trim', $row);

                Fein das, das erfüllt ja auch Iteration vor Rekursion.

                Gruß

                jobo

  3. Hallo jobo,

    $tab[0]=array("   haaa ","xxx   ");
    $tab[1]=array("   ffhaaa ","   dddxxx   ");

    gebe ich mal meinen Senf auch noch dazu:

    Irgendwo müssen die Daten ja herkommen. Wäre es da nicht besser vornherein die Daten so zu speichern, wie man sie später benötigt?

    Gruß aus Berlin!
    eddi

    1. moin Eddi,

      Irgendwo müssen die Daten ja herkommen. Wäre es da nicht besser vornherein die Daten so zu speichern, wie man sie später benötigt?

      Das ist feiner Senf mit Chili. Davon hab ich heute nacht geträumt ;-)

      Hotti

      1. Morjens,

        Irgendwo müssen die Daten ja herkommen. Wäre es da nicht besser vornherein die Daten so zu speichern, wie man sie später benötigt?
        Das ist feiner Senf mit Chili. Davon hab ich heute nacht geträumt ;-)

        es ist schön, dass genau Du Dich dazu meldest. Als ich die Nachricht schrieb, schwirrte mir nämlich noch Dein Problem im Hinterkopf herum. Warum machst Du Dir da so ein Problem, wenn Du einen einzelnen Namen als array mit nur einem Wert anlegen kannst. Somit sollte sich doch das Problem, ob ein oder mehrere Werte enthalten sind, gar nicht stellen. Dann kannst Du mit einer Schleife drübergehen wie Jesus übers Wasser.

        Gruß aus Berlin!
        eddi

    2. Hallo EE,

      Irgendwo müssen die Daten ja herkommen. Wäre es da nicht besser vornherein die Daten so zu speichern, wie man sie später benötigt?

      User/Admin hat Daten in Exceldatei, verwaltet sie da, macht bei Aktualisierungsbedarf daraus dann eine CSV-Datei und die wird hochgeladen. Da passiert es schon mal, dass da irgendwo ein Blank ist, der nicht sein muss. Grad auch in er ersten Zeile, die die Überschriften/Spaltentitel beinhaltet.

      Gruß

      jobo

      1. Hallo,

        User/Admin hat Daten in Exceldatei, verwaltet sie da, macht bei Aktualisierungsbedarf daraus dann eine CSV-Datei und die wird hochgeladen. Da passiert es schon mal, dass da irgendwo ein Blank ist, der nicht sein muss. Grad auch in er ersten Zeile, die die Überschriften/Spaltentitel beinhaltet.

        Supi, dann trim' doch einfach in der ankommenden CSV-Datei mit einer passenden RegEx, bevor die Daten in Arrays vergraben werden, die du dann umständlich abklappern musst.

        Gruß, Don P

        1. Hallo,

            
          <?php  
          class CSV  
          {  
          	// Wird mit CSV-Daten bestückt  
          	private $_table = NULL;  
          	  
          	function __construct($filePath) {  
          		$fileHandle = @fopen($filePath,"r");  
          		if ($fileHandle) {  
          			while (($row = fgetcsv($fileHandle)) !== false) {  
          				//exclude empty lines  
          				if (!is_array($row)) {  
          					continue;  
          				}  
          				// Whitespaces/Leerzeichen am Anfang und Ende einer jeden Zelle entfernen  
          				$this->_table[] = array_map("trim",$row);  
          			}	  
          			// merci handle, go free  
          			fclose($fileHandle);  
          		}  
          	}	  
          	  
          	public function getTable() {  
          		if (NULL !== $this->_table) {  
          			return $this->_table;  
          		}  
          		return false;  
          	}  
          }  
          $csv = new CSV("test.csv");  
          var_dump($csv->getTable());  
          
          

          so siehts jetzt aus.

          Gruß

          jobo

          1. Hallo,

            so siehts jetzt aus.

            Gefällt mir nicht. Es ist ja fast dasselbe wie die rekursive Lösung, nur mit viel mehr Code. Es werden wiederum Arrays durchlaufen und jedes Element einzeln getrimmt. Da ist deine Rekursion vom Anfang viel eleganter.

            Ich dachte eher ans Einlesen der ganzen CSV-Datei (wenn sie nicht zu groß ist) und globales Entfernen aller Whitespaces vor und nach String-Delimitern mittels RegEx.
            Das geht wohl mit weniger Code und wäre performanter als das Durchlaufen der Arrays. Am besten, der User/Admin macht das mal kurz vor dem Hochladen, schließlich hat der's ja verbockt, hehe :P

            Für Perl wäre das ein Klacks...

            Gruß, Don P

            1. Hallo,

              Gefällt mir nicht. Es ist ja fast dasselbe wie die rekursive Lösung, nur mit viel mehr Code. Es werden wiederum Arrays durchlaufen und jedes Element einzeln getrimmt. Da ist deine Rekursion vom Anfang viel eleganter.

              Tja, aber ... http://www.refactoring.com/catalog/replaceRecursionWithIteration.html

              Für Perl wäre das ein Klacks...

              Na für PHP auch, weil es ja preg_match/_replace kennt (Perl Regular Expression G...???). Wäre mir hier aber zu heikel, dass das was falsches matched - irgendwann mal. trim() ist hier ja idiotensicher.

              Gruß

              jobo

              1. Hallo,

                Tja, aber ... http://www.refactoring.com/catalog/replaceRecursionWithIteration.html

                Das ist doch nicht die Bibel.
                Die bringen ja auch ein idiotisches Beispiel, für das man natürlich keine Rekursion bemühen würde. Rekursion ist doch nicht grundsätzlich schlecht.
                Wenn im konkreten Fall die Performance zweitrangig ist und du es übersichtlich und wartbar haben willst, dann bleib' doch einfach dabei.

                Wäre mir hier aber zu heikel, dass das was falsches matched - irgendwann mal.

                Irgendwann mal? Du traust dir aber nicht gerade viel zu. Wenn die Expression passt, dann passt sie, für immer. Computer machen keine Fehler ;)

                Gruß, Don P

                1. Hello,

                  Wäre mir hier aber zu heikel, dass das was falsches matched - irgendwann mal.

                  Irgendwann mal? Du traust dir aber nicht gerade viel zu. Wenn die Expression passt, dann passt sie, für immer. Computer machen keine Fehler ;)

                  Ist aber eine relativ teure Regular Expression. Siehe meinen Einwand in https://forum.selfhtml.org/?t=195443&m=1308350

                  Liebe Grüße aus dem schönen Oberharz

                  Tom vom Berg

                  --
                   ☻_
                  /▌
                  / \ Nur selber lernen macht schlau
                  http://bergpost.annerschbarrich.de
            2. Hello,

              Ich dachte eher ans Einlesen der ganzen CSV-Datei (wenn sie nicht zu groß ist) und globales Entfernen aller Whitespaces vor und nach String-Delimitern mittels RegEx.

              Das ist aus drei Gründen unwirtschaftlich. Regular Expressions sind teuer. Die hier benötigte Regular Expression ist besonders teuer, weil Field-Separators, die innerhalb von Field-Delimiters stehen, nicht behandelt werden durche. Sie gehören zu den Binnendaten. Und außerdem führt die fgetcsv()-Funktion den größten Teil davon dann nochmal durch, um die Felder voneinander zu trennen.

              Das Durchlaufen des Arrays und Anwenden der einfachen Trim-Funktion ist daher aller Wahrscheinlichkeit nach die billigste Variante.

              Liebe Grüße aus dem schönen Oberharz

              Tom vom Berg

              --
               ☻_
              /▌
              / \ Nur selber lernen macht schlau
              http://bergpost.annerschbarrich.de
          2. Hello,

              		//exclude empty lines  
              		if (!is\_array($row)) {  
              			continue;  
              		}  
            

            Das ist falsch.

            Eine leere Zeile wurde bis zu PHP 5.2.9(?) als Array mit einem leeren Element berücksichtigt (Bug) und danach, wie im Handbuch beschrieben, mit einem Array mit einem Element, das  NULL enthält.

            Liebe Grüße aus dem schönen Oberharz

            Tom vom Berg

            --
             ☻_
            /▌
            / \ Nur selber lernen macht schlau
            http://bergpost.annerschbarrich.de
            1. Hallo Tom,

              Eine leere Zeile wurde bis zu PHP 5.2.9(?) als Array mit einem leeren Element berücksichtigt (Bug)

              Das wuerde mich ja mal naeher interessieren. Kannst du mir bitte den offiziellen Link zum PHP-Bugtracker angeben? Besten Dank!

              Es grueszt
              Chris

              1. Hello,

                Eine leere Zeile wurde bis zu PHP 5.2.9(?) als Array mit einem leeren Element berücksichtigt (Bug)
                Das wuerde mich ja mal naeher interessieren. Kannst du mir bitte den offiziellen Link zum PHP-Bugtracker angeben? Besten Dank!

                Du hättest Dir das auch selber raussuchen können, aber ich war mal so frei... :-)

                http://bugs.php.net/bug.php?id=48313

                Liebe Grüße aus dem schönen Oberharz

                Tom vom Berg

                --
                 ☻_
                /▌
                / \ Nur selber lernen macht schlau
                http://bergpost.annerschbarrich.de