Schauen Sie voraus, wenn Sie ein Array in PHP iterieren
Frage
Ist es möglich, einen Blick nach vorne zu werfen, während ein Array in PHP 5.2 iteriert wird?Beispielsweise verwende ich foreach oft, um Daten aus einem Array zu manipulieren:
foreach($array as $object) {
// do something
}
Aber ich muss beim Durchsuchen des Arrays oft einen Blick auf das nächste Element werfen.Ich weiß, ich könnte einen gebrauchen for
Schleife und referenziere das nächste Element anhand seines Index ($array[$i+1]
), aber es würde nicht für assoziative Arrays funktionieren.Gibt es eine elegante Lösung für mein Problem, vielleicht mit SPL?
Lösung
Sie können den CachingIterator für diesen Zweck.
Hier ist ein Beispiel:
$collection = new CachingIterator(
new ArrayIterator(
array('Cat', 'Dog', 'Elephant', 'Tiger', 'Shark')));
Der CachingIterator ist immer ein Schritt hinter dem inneren Iterator:
var_dump( $collection->current() ); // null
var_dump( $collection->getInnerIterator()->current() ); // Cat
Wenn Sie also foreach
über $collection
tun, wird das aktuelle Element des inneren ArrayIterator das nächste Element schon sein, so dass man in sie spähen:
foreach($collection as $animal) {
echo "Current: $animal";
if($collection->hasNext()) {
echo " - Next:" . $collection->getInnerIterator()->current();
}
echo PHP_EOL;
}
Will Ausgabe:
Current: Cat - Next:Dog
Current: Dog - Next:Elephant
Current: Elephant - Next:Tiger
Current: Tiger - Next:Shark
Current: Shark
Aus irgendeinem Grunde kann ich nicht erklären, wird der CachingIterator immer versuchen, das aktuelle Element in einem String zu konvertieren. Wenn Sie iterieren eine Objektsammlung und Notwendigkeit, den Zugang Eigenschaften wollen, ein Verfahren CachingIterator::TOSTRING_USE_CURRENT
als zweiten param an den Konstruktor übergeben.
Auf Nebenbei bemerkt, bekommt der CachingIterator seinen Namen von der Fähigkeit, alle die Ergebnisse zwischenzuspeichern es bisher iteriert hat. Damit dies funktioniert, müssen Sie es mit CachingIterator::FULL_CACHE
instanziiert und dann können Sie das gespeicherte Ergebnis mit getCache()
holen.
Andere Tipps
Mit array_keys
.
$keys = array_keys($array);
for ($i = 0; $i < count($keys); $i++) {
$cur = $array[$keys[$i]];
$next = $array[$keys[$i+1]];
}
Sie können mit next
und prev
ein Array iterieren. current
gibt den aktuellen Wert Elemente und key
die aktuellen Schlüssel.
So können Sie etwas tun könnte:
while (key($array) !== null) {
next($array);
if (key($array) === null) {
// end of array
} else {
$nextItem = value($array);
}
prev($array);
// …
next($array);
}
Ich weiß, dass dies eine alte Post, aber ich kann jetzt besser, dass Strom / nächsten / vorherige Sache erklären. Beispiel:
$array = array(1,2,3,2,5);
foreach($array as $k => $v) {
// in foreach when looping the key() and current()
// is already pointing to the next record
// And now we can print current
print 'current key: '.$k.' and value: '.$v;
// if we have next we can print its information too (key+value)
if(current($array)) {
print ' - next key: '.key($array).' and value: '.current($array);
// at the end we must move pointer to next
next($array);
}
print '<br>';
}
// prints:
// current key: 0 and value: 1 - next key: 1 and value: 2
// current key: 1 and value: 2 - next key: 2 and value: 3
// current key: 2 and value: 3 - next key: 3 and value: 2
// current key: 3 and value: 2 - next key: 4 and value: 5
// current key: 4 and value: 5
Ich weiß, dass ich eine for-Schleife verwenden und das nächste Element anhand seines Index ($array[$i+1]) referenzieren könnte, aber für assoziative Arrays würde das nicht funktionieren.
Erwägen Sie die Konvertierung Ihres assoziativen Arrays in ein sequentiell indiziertes Array mit array_values(), sodass Sie die einfache for-Schleifenlösung verwenden können.