PHP Element aus mehrdimensionalem Array löschen

ismon

Lieutenant
Registriert
Dez. 2006
Beiträge
718
Hallo zusammen,

Ich bin gerade dabei mich etwas in das Thema Programmieren einzuarbeiten und habe mich dazu entscheiden dies mit PHP zu machen.

Aktuell beschäftige ich mich mit mehrdimensionalen Array.
Klappt auch alles soweit gut.

Nur würde ich gerne aus einem solchen Array einen Eintrag löschen ohne dass dabei ein leerer Eintrag zurückbleibt (also der Index).

Dazu habe ich mir folgendes überlegt:

Code:
foreach($meinArray as $meinWert1)
{
	
	foreach($meinWert1 as $meinWert2)
	{
					
		if($meinWert2!=$meineSuche)
		{		
		
			for($a=0;$a<count($meinWert1);$a++)
			{	
						#unset($meinArray[$i][$a]);	
						$testArray[$i][$a]=$meinArray[$i][$a];		
			}
							
		}else
		{
		
		}	
	}	
$i++;	
}

Erklärung:
$meineSuche ist das element das gelöscht werden soll
$meinArray ist das ausgangs Array
$testArray ist das neue Array welche ohne den gesuchten Eintrag erzeugt werden soll

Ich möchte also immer dann wenn das aktuelle Element das Array nicht auf den zu löschenden Wert passt dass dieser Eintrag in das neue Array geschrieben wird.
Wenn der gesucht Wert auf das aktuelle Element passt dann soll dieses Element nicht in das neue Array geschrieben werden.

Leider funktioniert das so nicht. Das neue Array sieht immer genau so aus wie das Alte.

Hat jemand eine Idee was ich falsch machen?

Gruß
Simon
 
Wie wärs wenn du das Element einfach raus löschst und die Werte aus dem alten Array in ein neues überträgst, dabei aber mit einer IF-Abfrage den leeren Eintrag überspringst?
 
Warum gehst du nicht über die Keys sondern verwendet noch extra Counter? Das ganze macht das nur aufwändiger, schwerer zu lesen und fehleranfälliger.

Hier ein Beispiel:

Code:
foreach($meinArray as $firstDimKey => $meinWert1){
    foreach($meinWert1 as $secondDimKey => $meinWert2){
        if($meinWert2 != $meineSuche){
            unset($meinArray[$firstDimKey][$secondDimKey]);
        }
    }
}

Mit unset() warst du mMn schon richtig. Der Code oben ist aber nicht getestet.

Generell sind mehrdimensionale Arrays eh schon schwer zu lesen und nach Möglichkeit zu vermeiden. Was genau möchtest du bauen, vielleicht gibt es ja einen eleganteren Weg das anzustellen?

Mit dem Code oben hast du am Ende in $meinArray das Array ohne Suchergebnis. Wenn du das Ursprungsarray behalten willst, musst du das so machen:

Code:
$newArray = $meinArray;
foreach($newArray as $firstDimKey => $meinWert1){
    foreach($meinWert1 as $secondDimKey => $meinWert2){
        if($meinWert2 != $meineSuche){
            unset($newArray[$firstDimKey][$secondDimKey]);
        }
    }
}
 
Zuletzt bearbeitet:
Hi,

- benutze array_intersect bzw. array_diff, um Übereinstimmungen bzw Unterschiede in den Arrays zu finden (siehe z.B. hier)
- wenn das Array an stelle X nicht mit dem gesuchten übereinstimmt mach einfach einen array_push mit dem Element in das testArray, das die Ausgabe beinhaltet

Ausgabe: das testArray hat alle Elemente, die nicht mit den gesuchten Werten übereinstimmen

Ansonsten: Wenn es reicht, dass die Werte im ursprünglichen Array gelöscht werden, d.h. also, dass du das ursrpüngliche Array danach nicht mehr in der ursprünglichen Form brauchst ist der Ansatz von Uepsilon perfekt.

VG,
Mad
 
Hallo,

erstmal danke für die Antworten.

Also wenn ich mit unset arbeite. Dann passiert folgendes.

Vor dem löschen sieht mein Array so aus:

200|Helga|Maier|Kiel
100|Simon|Müller|Berlin
300|Karl|Heinz|München
555|Otte|Google|Mannheim
999|Michael|Menger|Frankfurt
777|Dirk|von Basten|Köln

Nach dem löschen von z.B. Nummer 555 so:

200|Helga|Maier|Kiel
100|Simon|Müller|Berlin
300|Karl|Heinz|München

999|Michael|Menger|Frankfurt
777|Dirk|von Basten|Köln

Also eigentlich alles richtig nur das ich dann diesen leeren Index im Array habe.


gruß
Simon
 
Hi,

klar, "unset" bedeutet ja auch nicht, den Index zu löschen. Ein Array besteht per Definition nunmal genau aus solch einer Abfolge. Eine dynamische Alternative dazu ist in vielen Sprachen die "Liste". Aber man muss bedenken, dass durch die klare Zuweisung bei einem Array von Element und Position eine datenbankähnliche Indizierung und dadurch ein großer Performance-Vorteil besteht.

Wenn du die Lücke nicht haben willst kannst du zwei Möglichkeiten nutzen:
1. Wie schon geschrieben, erzeuge dir ein neues Array, in dem nur die gewünschten Elemente enthalten sind.
2. Lies dir das hier durch.

VG,
Mad
 
Hi,

eigentlich wollte ich ja mit dem Code den ich im ersten Beitrag geschrieben hatte ein neues Array erzeugen welches nur die gewünschten Elemente enthält aber das hat so leider nicht funktioniert.

Bei der Funktion array_values() bin ich mir nicht sicher wie ich die in meinem Fall anwenden soll.

Ich versuch mal noch weiter.
 
mit

$array = array_values($array);

kannst du aus dem array mit den löchern ein neues erstellen wo die löcher weggestrichen werden und alle indizes neu gesetzt werden, mMn genau das was du suchst. oder?

edit: zu spät...
 
Wenn Du Deinen Ansatz weiterverfolgen möchtest, und ich die Frage richtig verstanden habe, dann ist dein Problem, dass du bei der Zuweisung des Wertes einen fixen Index angibst.

probiers z.B. damit *ungetestet*

Code:
foreach($meinArray as $meinWert1)
{
	
	foreach($meinWert1 as $meinWert2)
	{
					
		if($meinWert2!=$meineSuche)
		{		
			$testArray[] = array();
			for($a=0;$a<count($meinWert1);$a++)
			{	
						#unset($meinArray[$i][$a]);	
						$testArray[count($testArray)-1][$a]=$meinArray[$i][$a];		
			}
							
		}else
		{
		
		}	
	}	
$i++;	
}

Wenn die Suche erfolglos war, dann wird ein leeres Array ans Ende von testArray gehangen. In der folgenden Schleife beziehst du Dich dann durch das count() immer auf das letzte Element im TestArray.

Es kann aber gut sein, dass ich hier nur Mist geschrieben hab ^^ Ist ja schliesslich mein erstes Posting *hoho*
 
Das habe ich schon so versucht:
Aus dem Array meinArray lösche ich den gesuchten Eintrag.

Dann mache ich folgendes:
$testArray=array_values($meinArray);

Wenn ich dann das neue Array ausgebe ist dort die gleiche Lücke drin.
Ich vermute ich nutze diese Funktion nicht richtig.
 
Hi,

@MastaE

Wenn man einfach an der letzten Stelle ein Element hinzufügen will nutzt man "push"

@TE

Wenn du meinst, du benutzt den Code falsch dann poste doch mal die Version, mit der du es jetzt versuchst, dann können wir auch sagen was daran falsch ist.

VG,
Mad
 
Hier der ganze Code dieses versuches:
Code:
<?php

$meineDB=file("DB.txt");
$meineSuche=$_POST["loeschen"];

$meinArray=array();



for($i=0;$i<count($meineDB);$i++)
{
$meinArray[]=explode("|",$meineDB[$i]);
}


#Löschen

$i=0;
foreach($meinArray as $meinWert1)
{
	
	foreach($meinWert1 as $meinWert2)
	{
					
		if($meinWert2!=$meineSuche)
		{		
			
			for($a=0;$a<count($meinWert1);$a++)
			{	
						#unset($meinArray[$i][$a]);
						$testArray[$i][$a]=$meinArray[$i][$a];
			}
							
		}
	}	
$i++;	
}

#Ausgeben

foreach($testArray as $meinWert1)
{
$i=0;		
	
	foreach($meinWert1 as $meinWert2)
	{
		if($meinWert2!=" ")
		{
			if($i!=3)
			{
				echo $meinWert2."|";
			}else
			{
				echo $meinWert2;		
			}
		}
		$i++;
	}
	echo "<br>";
}
echo "<br>";
echo "<a href=\"index.html\"> Zurück zur Eingabe</a>";

?>

Die Inhalte des Array kommen aus einer Text Datei namens DB.txt
Diese Textdatei hat folgenden Inhalt:
Code:
200|Helga|Maier|Hauenstein
100|Simon|Müller|Berlin	
300|Karl|Heinz|München
555|Otte|Google|Mannheim
999|Michael|Menger|Frankfurt
777|Dirk|von Basten|Köln
 
Hi,

du unsettest den Wert und schreibst ihn dann in das neue Array... fällt dir daran nichts auf? Und wo benutzt du dort "array_values"?

VG,
Mad
 
Nein, weil ich ja eigentlich den ersten Ansatz verfolgen wollte und nur die Daten in das neue Array schreiben möchte die der Bedingung (if($meinWert2!=$meineSuche)) entsprechen.

Und genau da verstehe ich nicht warum es nicht funktioniert.

Angenommen mein Suchsting ist 555, dann sollte er die Anweisung die in der IF Abfrage steht, immer dann machen wenn das aktuell Element des Array nicht 555 ist. D.H. im Umkehrschluss ja eigentlich das wenn das aktuelle Element im Array == 555 ist, dann wird die Anweisung nicht ausgeführt. Und wenn die Anweisung nicht ausgeführt wird sollte das Element auch nicht in das neue Array geschrieben werden.

Schein wohl irgendwie keine so einfache Kiste zu sein... :-)
 
PHP:
<?php

$meineDB=file("DB.txt");
$meineSuche=$_POST["loeschen"];

$meinArray=array();



for($i=0;$i<count($meineDB);$i++)
{
$meinArray[]=explode("|",$meineDB[$i]);
}


#Löschen
$testArray = array();
foreach($meinArray as $row => $columns)
{
	//default setzen
	$ignoreRow = false;
	
	foreach($columns as $columnvalue)
	{
					
		if($columnvalue == $meineSuche)
		{
			//Wert gefunden, markieren
			$ignoreRow = true;
			//können an dieser Stelle den Loop abbrechen
			break;
		}
				
	}
	
	//wenn der zu suchende Bestandteil nirgends gefunden wurde, dann die aktuellen Werte übernehmen und ins ausgabearray übertragen.
	if($ignoreRow == false) {
		$testArray[] = $columns;
	}
}


#Ausgeben

foreach($testArray as $meinWert1)
{
$i=0;		
	
	foreach($meinWert1 as $meinWert2)
	{
		if($meinWert2!=" ")
		{
			if($i!=3)
			{
				echo $meinWert2."|";
			}else
			{
				echo $meinWert2;		
			}
		}
		$i++;
	}
	echo "<br>";
}
echo "<br>";
echo "<a href=\"index.html\"> Zurück zur Eingabe</a>";

?>

Funktioniert bei einer beliebigen Suche eines Wertes - egal ob 555, Karl oder Heinz zu löschen sind....
Ist aber natürlich um einiges modifiziert. Wenn Du Fragen hast dann frag ruhig.

@Madman1209
[] ist das gleiche wie array_push

;)
 
Zuletzt bearbeitet: (typo 2 ^^)
Hi,

@MastaE

Aber $testArray[count($testArray)-1]= "Apfel" ist doch nicht so schön wie array_push($testArray, "Apfel"). Wenn du ein Element an das Array anhängen willst (an die letzte Stelle) ist array_push einfach das mittel der Wahl. Erst über count die Länge herauszufinden und dann "-1" halte ich für "von hinten durch die Brust ins Auge", zumal ja push genau dafür gedacht ist.

VG,
Mad
 
@Madman, wir reden aneinander vorbei. Du hast ja recht mit dem was du schreibst. Das "dranhängen" bezog sich meinerseits auf ein paar Zeilen über dem Countzeug. => $testArray[] = array();

Die Ausführungen mit dem dem count() bezogen sich dann eher darauf, dass somit sicher gestellt wäre, die Werte in das letzte BESTEHENDE Arrayelement zu schreiben.

Deswegen mein ich, aneinander vorbei :)
Nun aber back to topic.
 
Zurück
Oben