Iterate in Reverse Through an Array with PHP - Spl Solution

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 be

class 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 construct

foreach($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



Leave a reply



Submit