Trimmen der Werte eines zweidimensionalen Arrays
jobo
- php
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
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
hi,
geht das besser?
Iteration statt Rekursion.
Hotti
Hallo,
Iteration statt Rekursion.
Zwei geschachtelte foreach-Schleifen und dann die Wert kopieren?
Gruß
jobo
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!
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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