[php] unset() Frage

Katsumi

Lt. Commander
Registriert
Sep. 2002
Beiträge
1.336
Guten Morgen.

Ich möchte aus einem Array diverse Einträge entfernen per Index.
Das wollte ich mit unset() tun jedoch löscht er nicht nur den Eintrag, sondern auch den Index.

aus Array[0] Array[1] Array[2] würde beim löschen von unset(Array[1]) dann Array[0] Array[2] werden. Ein ansprechen des Array[1] würde nun zu Fehlern führen. Wie kann man das umgehen? Das Gesamt Array ist 500 und 21 sind es. Mögliche Lösung wäre ein verschieben statt löschen aber das wäre verdammt viel Prozessorzeit(Abarbeitszeit) die da draufgehen würde. Weis wer eine bessere Lösung?
 
Such mal bei php.net in den Array Funktionen. Da gibts sicherlich eine für.

Ansonsten selbst schnell eine schreiben, die das gewünschte Ergebnis liefert.
 
Ich kenne php.net so wie jeder der mit php was zu tun hat und ich habe auch wie auch jeder die Hilfe als offline Nachschlagewerk. Brachte mir leider nichts, da ich sonst nicht fragen müsste. EIne eigene schreiben geht dir bemerkenswert schnell über die Lippen. Wie ich schon sagte würde mir nur das verschieben als Lösung einfallen und das ist zu Zeitintensiv da ich schliesslich noch mehr im Script mache. Nährwert des Kommentars = NULL ;)

Kein php Profi hier der mal eine etwas professionellere Antwort parat hat?
Traut euch! ^__^ Ist wirklich wichtig :(

Nachtrag:
Mir fällt grad noch eine mögliche schnellere Lösung ein. Kopieren des Arrays in ein neues Array ohne den zu löschenden Eintrag. Sollte wesentlich schneller sein als das verschieben aller Elemente.
 
Zuletzt bearbeitet:
Ja das ist mein Nachtrag ;)
Damit kopiere ich ein Teil des Array in ein anderes. Bin jedoch jetzt auf das Problem gestossen das wie hinten anfügen? array_push() ist nicht geeignet da ich dort wieder Index für Index kopieren müsste und einem verschieben gleichkommt. Ein Anhängen per [] fügt es logischerweise als "unter Array" ein. Tja wie füge ich nun hinten dran? So das der Index von vorne bis hinten durchlaufend ist und nicht Index für Index kopieren muss.
 
Vielleicht bringt der Ursprungscode etwas
$var ist ein Array von 21 Arrays mit in meinem momentanen Fall je 500 Untereinträgen
min $var[0][0]
max $var[21][499]

PHP:
$x=1;	
while (count($var[0])>150)
{
	for ($z=0;$z<21;$z++)
	{
		unset($var[$z][$x]);
	}

	$x+=2;
	if ($x>147) $x=1;
}

Da der Index aber durch unset() zerstört wird (tatsächlich entfernt) ist ein späteres ansprechen mit [$x] fatal und wird zu einer Endlosschleife.

Ich möchte in diesem Beispiel aus den 500 Einträgen 150 machen indem ich von vorne nach hinten jeden 2. Eintrag lösche und wenn Ende erreicht von vorne beginne bis eben 150 übrig sind.

Jede echte Hilfe wird dankend entgegen genommen ;)
 
Katsumi schrieb:

Ich hab's mal mit nem eindimensionalen Array ausgeknobelt.

PHP:
$var = array();
for ($i = 0; $i < 500; $i++) {
		$var[$i] = $i;
	}
	
	print_r ($var);
	echo "\n\n";
		 	
		while (count($var) > 150)
		{
		   	for ($i = 1; $i < count($var); $i+=2 ) {
		   		if (count($var) > 150) {
		   			array_splice($var, $i, 1);
		   		}
		   		else break;
			}
		}
		
		print_r ($var);

Damit sollte sich Dein gewünschter Effekt erzielen lassen.

Ciao


[EDIT:] Mensch da hatte sich doch glatt nen Fehler eingeschlichen. ;)
 
Zuletzt bearbeitet:
PHP:
$x=1;    
while (count($var[0])>150)
{
    for ($z=0;$z<21;$z++)
    {
        //unset($var[$z][$x]);
        array_splice($var[$z],$x,1);
    }

    $x+=2;
    if ($x>147) $x=1;
}

Der Code geht auch ^^
Ist übersichtlicher und kleiner ;)
Durch sein 2. for() muss eine 2. Abfrage gemacht werden ob man über den count() bereits ist und den ("mirc") Syntax find ich persönlich zum kotzen. Ich weiss es ist irgendwie ein 2. Standard aber ich mag diesen garnicht. :)
 
Katsumi schrieb:
PHP:
$x=1;    
while (count($var[0])>150)
{
    for ($z=0;$z<21;$z++)
    {
        //unset($var[$z][$x]);
        array_splice($var[$z],$x,1);
    }

    $x+=2;
    if ($x>147) $x=1;
}

Der Code geht auch ^^
Ist übersichtlicher und kleiner ;)
Durch sein 2. for() muss eine 2. Abfrage gemacht werden ob man über den count() bereits ist und den ("mirc") Syntax find ich persönlich zum kotzen. Ich weiss es ist irgendwie ein 2. Standard aber ich mag diesen garnicht. :)


Damit erreichst du aber nicht den von Dir gewünschten Effekt, zumindest nicht so, wie ich es verstanden habe.

Ich gebe Dir mal beide Codeteile.
Zunächst mal meine Lösung.
PHP:
<?php
	$var = array();
	for ($i = 0; $i < 500; $i++) {
		$var[$i] = $i;
	}
		 	
	while (count($var) > 150)
	{
	   	for ($i = 1; $i < count($var); $i+=2 ) {
	   		if (count($var) > 150) {
	   			array_splice($var, $i, 1);
	   		}
	   		else break;
		}
	}	
	print_r ($var);		
?>

Und nun Deine Lösung:
PHP:
<?php
	$var = array();
	for ($i = 0; $i < 500; $i++) {
		$var[$i] = $i;
	}

	$x=1;
	while (count($var)>150)
	{
		array_splice($var,$x,1);	
	    $x+=2;
	    if ($x>147) $x=1;
	}
	print_r ($var);
?>

Vergleiche mal die Ausgaben miteinander. Bei Dir ist ab Index [108] => 458 eine fortlaufende Reihe. Bei mir zieht sich die Entropie bis zum Schluss durch und dies ist der Effekt, den Du beschrieben hast und meiner Meinung nach erzielen wolltest.

[EDIT]

Um mit Deinem Code den gleichen Effekt zu erzielen musst Du diese Zeilen
PHP:
$x+=2;
if ($x > 147) $x=1;

durch diese hier ersetzen:
PHP:
 $x = ($x > count($var)) ? 1 : $x+2;

Ciao
 
Zuletzt bearbeitet:
ups ja stimmt da war nen böser fehler drin den auch gleich verbessert hast

PHP:
$x+=2;
if ($x+2>count($var)) $x=1;

allerdings (was ich nicht erwähnte) muss das so sein da es mit dem ersten und letzten Eintrag auch enden soll und nur innen drin Einträge Entfernt werden sollen. Sonst würde ein Diagramm plötzlich ganz woanders enden(anfangen).. das wollen wir ja nicht ;)


Jedoch.. sollte das nicht identisch sein?

PHP:
for ($i = 0; $i < 500; $i++) {
		$var[$i] = $i;
}

$x=1;
while (count($var)>150)
{
		array_splice($var,$x,1);        
	$x+=2;
	if ($x+2>count($var)) $x=1;
}
print_r ($var);


PHP:
$var = array();
for ($i = 0; $i < 500; $i++) {
		$var[$i] = $i;
}

while (count($var)>150)
{
		array_splice($var,$x,1);        
	$x = ($x+2 > count($var)) ? 1 : $x+2; 
}
print_r ($var);

Ab Index [41] gehen sie andere(ähnliche) Wege .. :konfus:


Nachtrag: ups das $x=1 vergessen beim 2. ^__^
dafür endet er jetzt bei 498 -_-
 
Zuletzt bearbeitet:
Hallo nochmal,

dass das letzte Element auch das letzte bleiben soll, hast du aber nicht erwähnt.

In dem Fall muss Du die Zeile:
PHP:
 $x = ($x+2 > count($var)) ? 1 : $x+2;

durch diese hier ersetzen:
PHP:
$x = (($x + 2) > (count($var) - 2)) ? 1 : ($x + 2);

So bleibt das letzte Element des Arrays unangetastet. Dummerweise dann aber auch das vorletzte Element, da dies niemals auf einer ungeraden Position stehen wird.

Teste das mal, wenn der Graph entsprechend ausssieht kannst du das ja nehmen. Ansonsten musst Du dir wohl oder übel einen besseren Weg zur Reduktion des Arrays suchen. Ich könnte mir vorstellen, dass ein Wechsel zwischen geraden und ungeraden Schlüsseln zu einem konsistenteren Ergebnis führen könnte.

[EDIT]
So ich hab das mal getestet. Hier der Code für den Fall, erst alle geraden Indizes ab 2 rausschmeissen, dann alle ungeraden und dann wieder ein Wechsel.
PHP:
<?php
	$var = array();
	for ($i = 0; $i < 500; $i++) {
		$var[$i] = $i;
	}

	$x=2; /* Starte mit den geraden Indizes. */
	while (count($var) > 150)
	{
		array_splice($var, $x, 1);
		$x = (($x + 2) > (count($var) - 2)) ? ((($x % 2) == 0) ? 1 : 2) : ($x + 2);
	}
	print_r ($var);
?>

Ich würde testen, welcher der Graphen dem Original am nähesten kommt und mich dann für eine Variante entscheiden.

Ciao
 
Zuletzt bearbeitet:
Zurück
Oben