Multidimensionales Array aus exploded String erstellen
Gunther
- php
Hallo werte Selfgemeinde,
ich bräuchte biite mal Hilfe, bzw. eine Idee, wie ich folgendes umsetzen kann:
Und zwar habe ich in einem Array mehrere Keys, die die Form "abc", "abc/def" oder "abc/def/.../xyz" haben.
Nun möchte ich jeweils aus diesen Keys, sofern sie die Form "abc/def/.../xyz" haben, ein multidimensionales Array erstellen, bei dem die Teile "abc", "def" usw. jeweils einen Array Schlüssel bilden und der letzte Teil ("xyz") den Wert.
Dazu zerlege ich den Key per explode() und iteriere über das so neu gewonnene Array.
Mein Problem besteht aber nun darin, dass ich keine Idee habe, wie ich jetzt mein multidimensionales Array erstellen soll?
Wichtig ist natürlich auch, dass entsprechende Schlüssel (Level) nur eingefügt werden, wenn sie noch nicht existieren. Andernfalls soll lediglich der Wert eingefügt werden.
Puh, gar nicht so einfach, mein Vorhaben verständlich zu formulieren. Ich hoffe, ihr versteht mich und mein Anliegen dennoch.
Für Tipps/ Ideen meinen besten Dank im Voraus!
Gruß Gunther
Moin
Das riecht stark nach Rekursion in Verbindung mit Call by Reference ;)
Gruß Bobby
Hello,
Das riecht stark nach Rekursion in Verbindung mit Call by Reference ;)
Ich begrüße Dich im Club.
Für die Umwanflung des Arrays in eine URL-Struktur ist das vermutlich unumgänglich. Ich habe das hier schan mal vorgestellt.
Für den Rückweg könnte man mMn vermutlich mit foreach() in Schachtelung und isset() zum Erfolg kommen.
Das wesentliche wird sein, dass man bei der ersten Umwandlung (Zeilen in Arrays) nicht aus versehen einen Zielwert ungleich NULL oder FALSE angibt. Dann lässt der sich nämlich nicht mehr mehrstufig überschreiben.
aus
$_myList['first'] -> 'black';
kann man direkt nicht mehr machen
$_myList['first']['background']['value'] -> 'black';
da $_myList['first'] breits vom Typ String ist und damit nicht implizit überschreibbar.
Wenn $_myList['first'] allerdings auf false oder NULL zeigt, dann lässt PHP die Typüberschreibung zu Array zu.
Soviel nur dazu, was zu beachten ist.
Bei der Expansion benötigt man keine Referenzen, bei der Implosuin schon.
Die Expansion funktimniert verlustfrei, die Implosion ist an Regeln gebunden, bzw. funktioniert nicht verlustfrei!
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Moin!
aus
$_myList['first'] -> 'black';
kann man direkt nicht mehr machen
$_myList['first']['background']['value'] -> 'black';
da $_myList['first'] breits vom Typ String ist und damit nicht implizit überschreibbar.
Wenn $_myList['first'] allerdings auf false oder NULL zeigt, dann lässt PHP die Typüberschreibung zu Array zu.
Man kann auch direkt ein leeres Array zuweisen.
Das Problem ist aber ein anderes:
"abc/def" ist der Key "abc" mit Value "def".
"abc/def/ghi" ist ['abc']['def'] als Key-Kette - aber ['abc'] ist kein vorher leeres Array, sondern der Value "def".
Die Frage ist also: Wie ist so ein Fall definiert?
Das Problem geht übrigens nicht weg, wenn man den eigentlichen Value im String anders abspaltet:
"abc = 1"
"abc/def = 2"
Hat dasselbe Problem: "abc" kann nicht gleichzeitig den Value 1 enthalten, und parallel das Array mit Key "def" sein. Da kommt man nur raus, wenn man in seinem Array mindestens noch einen Key "value" anlegt (und ausschließt, dass man selbst den Key "value" verwendet):
['abc']['value'] = 1
['abc']['def'] = array(...)
- Sven Rautenberg
Hello Sven,
$_myList['first'] -> 'black';
kann man direkt nicht mehr machen
$_myList['first']['background']['value'] -> 'black';
da $_myList['first'] breits vom Typ String ist und damit nicht implizit überschreibbar.
Wenn $_myList['first'] allerdings auf false oder NULL zeigt, dann lässt PHP die Typüberschreibung zu Array zu.
Man kann auch direkt ein leeres Array zuweisen.
Das Problem ist aber ein anderes:
"abc/def" ist der Key "abc" mit Value "def".
"abc/def/ghi" ist ['abc']['def'] als Key-Kette - aber ['abc'] ist kein vorher leeres Array, sondern der Value "def".
Die Frage ist also: Wie ist so ein Fall definiert?
Das Problem geht übrigens nicht weg, wenn man den eigentlichen Value im String anders abspaltet:
"abc = 1"
"abc/def = 2"Hat dasselbe Problem: "abc" kann nicht gleichzeitig den Value 1 enthalten, und parallel das Array mit Key "def" sein. Da kommt man nur raus, wenn man in seinem Array mindestens noch einen Key "value" anlegt (und ausschließt, dass man selbst den Key "value" verwendet):
['abc']['value'] = 1
['abc']['def'] = array(...)
... oder die Elemente müssen eben selber auch einen Typ haben, den _wir_ hier aber nicht sehen können. So funktioniert das ja in rekursiven Verzeichnisschemata
Da haben die Elemente entweder den Typ 'data' (oder 'file', ...), oder sie sind vom Typ 'dir', oder, oder, ...
Das ist dann Definitionssache, welche davon dann auch nebeneinander existieren dürfen
F /var/www/web
D /var/www/web/example.org
PHP stellt diese Möglichkeit in seinen Arraystrukturen nicht zur Verfügung und verhindert effektiv, dass Fehler passieren.
Ich denke, dass Gunther da noch ein paar Informationen nachlegen muss, wenn es zur Lösung führen soll :-)
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
hi,
Ich denke, dass Gunther da noch ein paar Informationen nachlegen muss, wenn es zur Lösung führen soll :-)
Soso, Du willst es wohl ganz genau sehen ;
// recursive Method
// Rekonstruiere das Array
private function reconstruct($key, &$stub = array()){
// LOOKUP durchgehen
foreach($this->LOOKUP as $child_key => $parent){
if($parent == $key){
// childs
if(isset($this->KVTAB[$child_key])){
$stub[$child_key] = $this->KVTAB[$child_key];
}
else{
// Rekursion $child_key
$this->reconstruct($child_key, $stub[$child_key]);
}
}
}
}
Horst
Hello Horst,
Ich denke, dass Gunther da noch ein paar Informationen nachlegen muss, wenn es zur Lösung führen soll :-)
Soso, Du willst es wohl ganz genau sehen ;
Ich befürchte, dass Du Svens und meine Einwände nicht berücksichtigt hast. Wenn ein Array-Element bereits mit einem Wert (also nicht false und nicht NULL) belegt ist, kann man diesen nicht einfach (implizit) zum Key umfunktionieren. PHP lässt keine Doppelbelegung zu.
Man kann ihn allerdings explizit umdeklarieren:
$_array['eins'] = 1;
geht nicht:
$_array['eins']['zwei'] = 2;
geht:
$_array['eins'] = array();
$_array['eins']['zwei'] = 2;
Dann ist aber der Wert 1 verloren!
Das meinten Sven und ich sinngemäß.
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Hello all,
Ich denke, dass Gunther da noch ein paar Informationen nachlegen muss, wenn es zur Lösung führen soll :-)
Soso, Du willst es wohl ganz genau sehen ;
Ich befürchte, dass Du Svens und meine Einwände nicht berücksichtigt hast. Wenn ein Array-Element bereits mit einem Wert (also nicht false und nicht NULL) belegt ist, kann man diesen nicht einfach (implizit) zum Key umfunktionieren. PHP lässt keine Doppelbelegung zu.
Man kann ihn allerdings explizit umdeklarieren:
$_array['eins'] = 1;
geht nicht:
$_array['eins']['zwei'] = 2;geht:
$_array['eins'] = array();
$_array['eins']['zwei'] = 2;Dann ist aber der Wert 1 verloren!
Das meinten Sven und ich sinngemäß.
Genau, und deshalb verwende ich die zweite Variante. ;-)
Der Order-Wert wird nur für die Sortierung gebraucht und interessiert anschließend (also nach der Sortierung) eigentlich nicht mehr. Aber wenn er schon mal da ist ..., bleibt er halt.
Ich habe übrigens inzwischen auch meine "fertige" Variante gepostet.
Ich hoffe, dass klärt die noch offenen Fragen?
Gruß Gunther
Hello,
Ich habe übrigens inzwischen auch meine "fertige" Variante gepostet.
Ich hoffe, dass klärt die noch offenen Fragen?
Die habe ich noch nicht durch, denn Du hast dafür leider die (verbalen) Randbedingungen noch nicht genannt und die implizite Dokumentation (also Kommentare innerhalb der Funktionen usw.) lässt ebenfalls zu Wünschen übrig.
Ich will Dich hier nicht ärgern. Ich glaube auch, dass Du das verstanden hast :-)
Es geht einfach nur um die Nachvollziehbarkeit einer Fragestellung oder eines Problems und wie das dann (vermeintlich) gelöst wurde.
Leider gibt es hier viel zu viele "Mediziner", die einfach nur Pillen ausschütten gegen das Symptom, anstatt danach zu fragen, woher die Krankheit stammt...
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
hi,
Ich befürchte, dass Du Svens und meine Einwände nicht berücksichtigt hast. Wenn ein Array-Element bereits mit einem Wert (also nicht false und nicht NULL) belegt ist, kann man diesen nicht einfach (implizit) zum Key umfunktionieren. PHP lässt keine Doppelbelegung zu.
Ach was ;)
Ne, Du hast Recht, Deine Einwände habe ich tatsächlich nicht berücksichtigt ;)
Horst
Moin!
Das riecht stark nach Rekursion in Verbindung mit Call by Reference ;)
Jep, das war's ...! ;-)
Manchmal ist das mit dem Wald und den Bäumen echt schwer, wenn man das Brett schon vorm Kopf hat ...!
Besten Dank, natürlich auch an alle anderen!
Gruß Gunther
Hello,
Besten Dank, natürlich auch an alle anderen!
Beispiel?
Lösung?
Das wäre das schönste Dankeschön und außerdem nochmal eine Abschlussprüfung für Dich. Du willst doch bestimmt alle möglichen Fälle erfassen? Meistens ist man selber schon mit einem erfolgreichen Spezialfall zufrieden ...
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Hello,
Besten Dank, natürlich auch an alle anderen!
Beispiel?
Lösung?
ja kommt ..., war mir gestern nur zu spät und außerdem habe ich noch eine Sortierfunktion dazu gebaut. Ich hoffe, mir sind beim anpassen an die Demo-Version hier keine Fehler unterlaufen!?
Im Original funktioniert es jedenfalls ...! ;-)
$paths = array(
'abc' => array('order' => '2'),
'abc/abc' => array('order' => '1'),
'abc/def' => array('order' => '3'),
'abc/ghi' => array('order' => '2'),
'def' => array('order' => '1'),
'def/abc' => array('order' => '2'),
'def/def' => array('order' => '1'),
'abc/def/abc' => array('order' => '2'),
'abc/def/def' => array('order' => '1'),
'ghi' => array('order' => '3')
);
$meinArray = array();
foreach($paths as $index => $tmp) {
if($index == 'frontpage') continue;
$indexes = explode('/', $index);
$counter = count($indexes);
if($counter > 1) {
$meinArrayReference = &$meinArray;
for($i = 0; $i < ($counter - 1); $i++) {
if (!array_key_exists($indexes[$i], $meinArrayReference)) {
$meinArrayReference[$indexes[$i]] = array();
}
$meinArrayReference = &$meinArrayReference[$indexes[$i]];
}
$meinArrayReference[$indexes[$i]] = array('order' => $tmp['order']);
}
else {
$meinArray[$indexes[0]] = array('order' => $tmp['order']);
}
}
uasort($meinArray, 'cmp');
$meinArray = sortMultiArray($meinArray);
print_r($meinArray);
exit;
function sortMultiArray($arr) {
foreach ($arr as &$subArr) {
if(count($subArr) > 1) {
uasort($subArr, 'cmp');
sortMultiArray($subArr);
}
}
return $arr;
}
function cmp($a, $b) {
if ($a['order'] == $b['order']) {
return 0;
}
return ($a['order'] < $b['order']) ? -1 : 1;
}
Macht zumindest jetzt das, was ich möchte und für die weitere Verarbeitung brauche.
Verbesserungsvorschläge sind natürlich jederzeit willkommen - danke!
Gruß Gunther
Mahlzeit,
würde ein einfaches array_merge() in die richtige Richtung gehen?
Hello,
was habe ich bisher verstanden?
Es gibt eine Stream, den man in Strings zerlegen kann.
Aus den Strings soll dann erstmal werden:
"abc" -> $_array['abc'] -> NULL;
"abc/def" -> $_array['abc']['def'] -> NULL;
"abc/def/bloedmann/xyz" -> $_array['abc']['def']['bloedmann']['xyz'] -> NULL;
Wird nun klar, wo erst einmal das Problem liegt?
Wenn es keine weiteren Metadaten zu den Fragmenten gibt, muss man da vermutlich mehrstufig vorgehen. Also erstmal aus dem Stream die Strings entwicklen, dann die Strings in Arrays umwandeln (explode()), dann die Arrays aus den Zeilen in ein Gesamt-Array übertragen
Und darauf liegt jetzt der Fokus :-O
Vorschläge?
Ich habe das umgekehrte Verfahren vor langer Zeit im Archiv hinterlassen, also wie man aus einer Raumstruktur ("Mutlidimensonales Array") eine normalisierte Datstellung erzeugen kann.
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg