Iterate in reverse through an array with PHP - SPL solution?
There is no ReverseArrayIterator
to do that. You can do
$reverted = new ArrayIterator(array_reverse($data));
or make that into your own custom iterator, e.g.class ReverseArrayIterator extends ArrayIterator
{
public function __construct(array $array)
{
parent::__construct(array_reverse($array));
}
}
A slightly longer implementation that doesn't use array_reverse
but iterates the array via the standard array functions would beclass ReverseArrayIterator implements Iterator
{
private $array;
public function __construct(array $array)
{
$this->array = $array;
}
public function current()
{
return current($this->array);
}
public function next()
{
return prev($this->array);
}
public function key()
{
return key($this->array);
}
public function valid()
{
return key($this->array) !== null;
}
public function rewind()
{
end($this->array);
}
}
Iterate array from the end without reverse
You can try this.
$new_array=end($a);
do {
// Your Code here
}
while ($new_array=prev($a));
Reverse SPLObjectStorage
SplObjectStorage
is a key->value store
and The "key" of an element in the SplObjectStorage
is in fact the hash of the object. Sorting and Reverting would require you to extend and write your own implementation but i think you should consider Using SplStack
Imagine your player class
class Player {
private $name;
function __construct($name) {
$this->name = $name;
}
function __toString() {
return $this->name;
}
}
Using SplStack
$group = new SplStack();
$group->push(new Player("Z"));
$group->push(new Player("A"));
$group->push(new Player("B"));
$group->push(new Player("C"));
echo "<pre>";
$infinite_it = new InfiniteIterator($group);
$limit_it = new LimitIterator($infinite_it, 0, 3); // get frist 3
foreach ( $limit_it as $p ) {
echo ("$p");
}
If you insist on SplObjectStorage
then you can consider a custom ReverseArrayIterator
class ReverseArrayIterator extends ArrayIterator {
public function __construct(Iterator $it) {
parent::__construct(array_reverse(iterator_to_array($it)));
}
}
Usage $group = new SplObjectStorage();
$group->attach(new Player("Z"));
$group->attach(new Player("A"));
$group->attach(new Player("B"));
$group->attach(new Player("C"));
echo "<pre>";
$infinite_it = new InfiniteIterator(new ReverseArrayIterator($group));
$limit_it = new LimitIterator($infinite_it, 0, 3); // get frist 3
foreach ( $limit_it as $p ) {
echo ("$p");
}
Both would Output CBA //reversed
How to do a for each from end of the array in PHP
Reverse the array and do a normal foreach
?
$newArray = array_reverse($array);
foreach ($newArray as $key => $value) {
...
}
Treat a PHP class that implements Iterator as an array
The purpose of the Iterator interface is to allow your object to be used in a foreach loop, it is not intended to make your object act like an array. If you want something that acts like an array, use an array.
You can always turn your object into an array by using the iterator_to_array function, but you can't reverse that process.
If you see the need for reversing the order of the elements in your iterable object, then you could create a reverse() method that, possibly, uses array_reverse() internally. Something like this:-
class Test implements Iterator
{
private $testing = [0,1,2,3,4,5,6,7,8,9,10];
private $index = 0;
public function current()
{
return $this->testing[$this->index];
}
public function next()
{
$this->index ++;
}
public function key()
{
return $this->index;
}
public function valid()
{
return isset($this->testing[$this->key()]);
}
public function rewind()
{
$this->index = 0;
}
public function reverse()
{
$this->testing = array_reverse($this->testing);
$this->rewind();
}
}
$tests = new Test();
var_dump(iterator_to_array($tests));
$tests->reverse();
var_dump(iterator_to_array($tests));
Output:-array (size=11)
0 => int 0
1 => int 1
2 => int 2
3 => int 3
4 => int 4
5 => int 5
6 => int 6
7 => int 7
8 => int 8
9 => int 9
10 => int 10
array (size=11)
0 => int 10
1 => int 9
2 => int 8
3 => int 7
4 => int 6
5 => int 5
6 => int 4
7 => int 3
8 => int 2
9 => int 1
10 => int 0
I wrote the code to prove to myself that it would work before posting and thought I might as well throw it into the answer. Custom iteration for SplObjectStorage
No, it's not possible. Internally SplobjectStorage
use the same data structure as an array (the HashTable
), but it's not an "array-array" as we know from the PHP userland: we only add values and not keys, as keys are actually generated from the values by hashing them (you can even overwrite this by overwriting the getHash
method). Another difference is that you can additionally add information to the object.
In short, SplObjectStorage should not be used as an array, but as either a set or a map, there lies its strength.
How to reverse order DirectoryIterator
As far as I know, there's no way to do it by setting a specific option or setting.
However, since all you want to do it just to reverse the order you can store the data in an array and then simply reverse the array.
<?php
$filesArr = array();
$path='files';
$Iterator = new DirectoryIterator($path);
foreach ($Iterator as $file) {
if ($file->isDot()) continue;
if ($file->isDir()) {
$filname=$file->getFilename();
$filname=str_replace(' ','-',$filname);
$filesArr[] = '<div class="catRow"><a href="http://'.$sitenameurl.'/category/'.$filname.'.html"><div>» '.$file->getFilename().'</div></a></div>';
}
}
$revFilesArr = array_reverse($filesArr);
foreach($revFilesArr as $fileRow){
echo $fileRow;
}
?>
How can I iterate through two arrays at the same time without re-iterating through the parent loop?
Use a normal for
loop instead of a foreach
, so that you get an explicit loop counter:
for($i=0; $i<count($content)-1; $i++) {
echo $content[$i].'-'.$contentb[$i];
}
If you want to use string based indexed arrays, and know that the string indexes are equal between arrays, you can stick with the foreach
constructforeach($content as $key=>$item) {
echo $item.'-'.$contentb[$key];
}
Iterating over multi-level ArrayObject() to print out on-screen hierarchical view
In my experience you should just use a recursive function call.
By that I mean you simple make a function that does whatever you need, but have a while loop at the end of the function that loops through the children and calls the function again on each child. This way you fire the function on every child of the original object.
Related Topics
MySQL into Outfile Override Existing File
Phpexcel Get Formatted Date as Is Visible in Excel File
Codeigniter 3 - Access Session from Outside Codeigniter Installation
Phpmailer - Mails Going Straight to Spam
Config Nginx for Laravel in a Subfolder
Rename Multiple Order Statuses in Woocommerce
I Want to Find Current Location of User in PHP
Php/MySQL with Encoding Problems
PHP Search Array Key and Get Value
Create a Joomla! Article Programmatically
PHP Exec() Command: How to Specify Working Directory
How to Sort Null Values Last Using Eloquent in Laravel
How to Call Curl_Setopt with Curlopt_Httpheader Multiple Times to Set Multiple Headers
PHP - Display a 404 Error Without Redirecting to Another Page