foreach - auf nächstes Element zugreifen und rückwärts laufen
X-Ray
- php
Hallo!
Gibt es eine einfache Möglichkeit, um in einer foreach-Schleife auf das folgende Element des Arrays zuzugreifen, das man durchläuft?
Beispiel-Array:
$fruechte = array(
'Apfel' => 'Baum',
'Traube' => 'Rebe',
'Haselnuss' => 'Strauch'
);
foreach ($fruechte as $frucht => $pflanze) {
// Wenn $frucht 'Apfel' enthaelt, moechte ich auch auf 'Traube' zugreifen koennen, wenn $frucht 'Traube' enthaelt, auch auf 'Haselnuss'
}
Und ist es möglich mit einer foreach-Schleife ein Array von hinten nach vorne zu durchlaufen?
Schönen Gruß
Stefan
Hi,
Gibt es eine einfache Möglichkeit, um in einer foreach-Schleife auf das folgende Element des Arrays zuzugreifen, das man durchläuft?
Innerhalb einer foreach-Schleife am Array-Pointer, der die aktuelle Position enthaelt, herumzuspielen, ist im allgemeinen keine gute Idee.
Es gaebe zwar Funktionen wie next() - aber die stellt den Pointer eben auch um eins vor, so dass beim naechsten Schleifendurchlauf ein Element uebersprungen wuerde.
Aber du kannst ja versuchen, dass Pferd andersherum aufzuzaeumen:
Nicht aktuelles und naechstes Element betrachten, sondern aktuelles und vorheriges.
Und ist es möglich mit einer foreach-Schleife ein Array von hinten nach vorne zu durchlaufen?
Ja - wenn du vorher array_reverse() auf's Array anwendest.
MfG ChrisB
Innerhalb einer foreach-Schleife am Array-Pointer, der die aktuelle Position enthaelt, herumzuspielen, ist im allgemeinen keine gute Idee.
wieder was gelernt, dachte bisher foreach lässt keine manipulation den pointers zu und arbeitet gänzlich mit einer eigenen logik, habs aber grade nachgelesen - bin wohl zu sehr vb/asp geschädigt ;)
Und ist es möglich mit einer foreach-Schleife ein Array von hinten nach vorne zu durchlaufen?
soweit ich weiß nicht, du kannst den zeiger (pointer) im array aber selbst manipulieren
Hello,
Und ist es möglich mit einer foreach-Schleife ein Array von hinten nach vorne zu durchlaufen?
soweit ich weiß nicht, du kannst den zeiger (pointer) im array aber selbst manipulieren
Und dazu gibt es auch noch array_slice() und array_slice(), die eventuell helfen können,
aber mit Vorsicht anzuwenden sind, wenn man die Schlüssel nicht verlieren will.
http://www.php.net/manual/en/function.array-slice.php
http://www.php.net/manual/en/function.array-splice.php
mit
$_element = array_slice($_array,$index,1,true)
sollte man gezielt ein Arrayelement über seine numerische Position in der Liste des jeweiligen Zweiges erhalten nebst assoziativem Key.
Den Key benötigt man dann, um ggf. am Element etwas manipulieren zu können.
Dies führt zwar nachher zu einer sauberen Lösung, aber Bastelei ist es auf jeden Fall noch. Bei der Mächtigkeit der Array-Funktionen fehlt hier mMn noch eine Gruppe.
Liebe Grüße aus Syburg bei Dortmund
Tom vom Berg
Lieber X,
foreach ($fruechte as $frucht => $pflanze) {
// Wenn $frucht 'Apfel' enthaelt, moechte ich auch auf 'Traube' zugreifen koennen, wenn $frucht 'Traube' enthaelt, auch auf 'Haselnuss'
}
Du hast ein assoziatives Array. Die Folge der Indices lässt sich daher nicht logisch ermitteln. Ich weiß nicht, an welcher (numerischen!) Stelle z.B. die Haselnuss steht.
Aber: Ich kann mir ein numerisches Array mit allen Indices des assoziativen Arrays generieren lassen. Wenn ich das entsprechende $key/$value-Paar aus diesem numerischen Array habe, kann ich automatisch aus diesem numerischen Array den "nächsten" Index des ursprünglichen (assoziativen) Arrays holen.
Im Grunde wirst Du Dir für Dein assoziatives Array ein "Helfer-Array" dynamisch erzeugen müssen, um mit dessen Hilfe eine numerische Übersicht über Deine Array-Schlüssel zu haben. Eine numerische Übersicht über die _Werte_ bekommst Du entsprechend mit array_values().
Um schneller den numerischen Index eines ursprünglichen $keys oder $values zu ermitteln, könnte es sinnvoll sein, das Helfer-Array umzukehren, sodass die numerischen Indices zu Werten und die Werte zu Indices werden. Im Falle der "ehemaligen Indices" dürfte das kein Problem sein, da bei diesen sichergestellt ist, dass sie einmalig sind.
Liebe Grüße,
Felix Riesterer.
Du hast ein assoziatives Array. Die Folge der Indices lässt sich daher nicht logisch ermitteln. Ich weiß nicht, an welcher (numerischen!) Stelle z.B. die Haselnuss steht.
äh?! ich steh jetzt auf der leitung - ob das array assoziativ ist oder nummerische keys verwendet, ist doch egal - es hat eine interne reihenfolge die unveränderlich ist und nach der wird es abgearbeitet - wenn dem nicht so wäre, hätte man wohl ein gewaltiges problem mit den sortierfunktionen, wenn die reihenfolge "willkürlich" oder alphabetisch ist
$fruechte = array(
'Apfel' => 'Baum',
'Traube' => 'Rebe',
'Haselnuss' => 'Strauch'
);
reset($fruechte );
while (list($key, $value) = each($fruechte )) {
echo $key . '->' . $value . "\n";
}
Hellihello
sowas wie:
$count = 0;
foreach ($assArray as $key = $value) {
$numArray[$count]["key"] = $key;
$numArray[$count]["value"] = $value;
}
und dann durchs numArray laufen...; ginge auch, oder?
Dank und Gruß,
Lieber suit,
Du hast ein assoziatives Array. Die Folge der Indices lässt sich daher nicht logisch ermitteln. Ich weiß nicht, an welcher (numerischen!) Stelle z.B. die Haselnuss steht.
äh?! ich steh jetzt auf der leitung - ob das array assoziativ ist oder nummerische keys verwendet, ist doch egal - es hat eine interne reihenfolge die unveränderlich ist und nach der wird es abgearbeitet
Wenn ich Dir mal eben "Stachelbeere" an den Kopf werfe, weißt Du dann, ob Du mit Erdnuss oder Orange kontern sollst? Nur weil Du weißt, dass jetzt gerade "Stachelbeere" dran ist, weißt Du in einem assoziativen Array in dem Moment des Schleifendurchlaufs keineswegs, wie der nächste Index lauten wird!
Liebe Grüße,
Felix Riesterer.
Hi,
Nur weil Du weißt, dass jetzt gerade "Stachelbeere" dran ist, weißt Du in einem assoziativen Array in dem Moment des Schleifendurchlaufs keineswegs, wie der nächste Index lauten wird!
Aber, wie ich ja bereits schrieb, welcher der vorherige war.
Man kann so ein "Problem" also idR. von
schleife() {
tu was mit $aktuellem und $naechstem
}
auf
schleife() {
tu was mit $vorherigem und $aktuellem
}
"transformieren".
MfG ChrisB
Wenn ich Dir mal eben "Stachelbeere" an den Kopf werfe, weißt Du dann, ob Du mit Erdnuss oder Orange kontern sollst? Nur weil Du weißt, dass jetzt gerade "Stachelbeere" dran ist, weißt Du in einem assoziativen Array in dem Moment des Schleifendurchlaufs keineswegs, wie der nächste Index lauten wird!
wieso - was spricht gegen echo next($array); prev($array);
?
den pointer des arrays einfach nach vorne verschieben und ausgeben und dann gleich wieder nach hinten verschrieben
Lieber suit,
wieso - was spricht gegen
echo next($array); prev($array);
?
ich denke da an den Fall, wenn Du gerade den letzten Index in Händen hast. Das mit next() führt dann wahrscheinlich zu entweder einer Fehlermeldung, oder eben nix, das darauffolgende prev() aber unweigerlich zu Chaos, da dann garantiert der vorletzte Index angepeilt wird, den wir ja eigentlich schon hatten...
Liebe Grüße,
Felix Riesterer.
ich denke da an den Fall, wenn Du gerade den letzten Index in Händen hast. Das mit next() führt dann wahrscheinlich zu entweder einer Fehlermeldung, oder eben nix, das darauffolgende prev() aber unweigerlich zu Chaos, da dann garantiert der vorletzte Index angepeilt wird, den wir ja eigentlich schon hatten...
und was spricht dagegen mit if(next($array)) {}
vorher zu prüfen, obs auch tatsächlich noch einen gibt?
zum thema chaos - das argument zieht nicht, du könntest genausogut sagen echo $_GET['foo'];
führt unweigerlich zum chaos, weil es könnte ja sein, dass foo nicht im querystring übergeben wird?
Hello,
und was spricht dagegen mit
if(next($array)) {}
vorher zu prüfen, obs auch tatsächlich noch einen gibt?
... dass der interne Arrayzeiger bereits durch diese Prüfung um eins weitergerückt wird und Du das Ergebnis nicht wirklich abgeholt hast, sondern nur geprüft hast, ob es eins gibt?
Das fällt dann unter "jede Messung verfälscht das Ergebnis", oder?
Liebe Grüße aus Syburg bei Dortmund
Tom vom Berg
... dass der interne Arrayzeiger bereits durch diese Prüfung um eins weitergerückt wird und Du das Ergebnis nicht wirklich abgeholt hast, sondern nur geprüft hast, ob es eins gibt?
Das fällt dann unter "jede Messung verfälscht das Ergebnis", oder?
richtig, darum dürfte man bei erfolgreicher prüfung natürlich nicht mehr mit next() sondern mit current() arbeiten und dann halt wieder mit prev() zurück
versteht mich nicht falsch, ich weiß, dass es kompliziert ist - aber die methode ist imho besser das array vorher in ein anderes array zu kopieren - das braucht doch unnötig speicher
wenn man sich das mit einem record set vorstellt mit sagen wir 100.000 datensätzen, da freut sich der server wenn er die dinger erst von einem in ein anderens datenformat transportieren darf, nur weil der programmierer mit dem "chaos" eines veränderbaren objekt- oder array-zeigers nicht umgehen kann
Hello,
... dass der interne Arrayzeiger bereits durch diese Prüfung um eins weitergerückt wird und Du das Ergebnis nicht wirklich abgeholt hast, sondern nur geprüft hast, ob es eins gibt?
Das fällt dann unter "jede Messung verfälscht das Ergebnis", oder?
richtig, darum dürfte man bei erfolgreicher prüfung natürlich nicht mehr mit next() sondern mit current() arbeiten und dann halt wieder mit prev() zurückversteht mich nicht falsch, ich weiß, dass es kompliziert ist - aber die methode ist imho besser das array vorher in ein anderes array zu kopieren - das braucht doch unnötig speicher
wenn man sich das mit einem record set vorstellt mit sagen wir 100.000 datensätzen, da freut sich der server wenn er die dinger erst von einem in ein anderens datenformat transportieren darf, nur weil der programmierer mit dem "chaos" eines veränderbaren objekt- oder array-zeigers nicht umgehen kann
Stimmt auch wieder.
Wenn man es aus der Ressourcen-Sicht betrachtet, erscheint mir Deine Idee gar nicht mehr so schlecht. Tanzen wir eben ein wenig Tango :-)
Liebe Grüße aus Syburg bei Dortmund
Tom vom Berg
Hellihello
auch wenns gleich Haue gibt hierfür:
<?php
// testarray
$myArray["a"] = "va";
$myArray["b"] = "vb";
$myArray["c"] = "vc";
$myArray["aa"] = "vaa";
$myArray["bb"] = "vbb";
$myArray["cc"] = "vcc";
// get Iterator
$myArrayIterator = new ArrayIterator($myArray);
// will be numeric key of current entry for orientation
$seekKey = 0;
foreach ($myArrayIterator as $key => $value) {
// finish if end is reached
if ($myArrayIterator->count() <= $seekKey +1) {
return;
}
// there must be an "a" in the key-name
if (strpos($key,"a") !== false) {
// get value of next entriy using numeric key of actual position
$myArrayIterator->seek($seekKey + 1);
// output for test purpose
echo "next value: ";
echo $myArrayIterator->current();
echo "\n";
// go back to where we came from (thats the seekKey for too
$myArrayIterator->seek($seekKey);
}
// next numeric key for or
$seekKey++;
}
?>
Dank und Gruß,