What are the ways to iterate an array in PHP (without foreach)?

Asked

Viewed 28,737 times

27

Before I am censured by the question, notice beforehand that the purpose of it is simply to level curiosity. I know that the foreach is the most suitable means for this.

But I would like to know the following:

What are the ways to iterate with a array in PHP, without using foreach, so that you can access índice and the valor (as in the foreach)?

I would like to see examples with for, while or even functions.

I’ll leave a array for response model:

$array = array(
    'stack' => 'Overflow',
    'linguagem' => 'Português',
    'tags' => array('PHP', 'Iteração', 'Array')
);

I need the interaction to happen this way (exemplifying with foreach):

foreach($array as $indice => $valor)
{
   var_dump($indice, $valor);
}

Heed: The only case not accepted for iteration with for is that of $i++, since it is a plastered way and only serves to array numerically indexed.

  • 1

    It would be interesting each one who answered exemplify with only one form :)

  • 3

    xD need to answer this question!

  • I didn’t quite understand how the exit should be, it should print tags and then 0, PHP... or 0, PHP?. 'Cause I’m running out therein

  • 2

    Excellent question, it is very cool to see that the community is very creative to give N solutions

12 answers

28


Being also a beginner, I became interested in the question and found an interesting article about it.

Here’s a solution according to the article.

$array = array(
    'stack' => 'Overflow',
    'linguagem' => 'Português',
    'tags' => array('PHP', 'Iteração', 'Array')
);

$keys = array_keys($array);

$size = count($array);

for ($i = 0; $i < $size; $i++) {
    $key   = $keys[$i];
    $value = $array[$key];

    echo $value;

}

See the code working on IDEONE

Ref: PHP Internals: When does foreach copy?

  • 2

    Now that I understand your iteration! I’ve noticed the injustice of Down vote. +1

  • If I may say so, @Iazyfox

  • I was trying to do without "indices" as you commented for (; isset($keys[0]); ) {&#xA; $key = $keys[0];&#xA; $value = $array[$key];&#xA;&#xA;&#xA; print($value);&#xA; &#xA; &#xA; array_shift($keys);&#xA;&#xA;} But without much success, now I’m also without much time :(

  • 1

    +1 for making with $i++, for breaking paradigms!!! rsrsrsrsr

  • 1

    @Sneepsninja, the question itself is already a breaking paradigm (maybe the answers!) kkkk

  • Despite not having a "right answer", I marked this by the majority votes

Show 1 more comment

14

It is also possible to iterate an array using the functions, array_walk() or array_walk_recursive(), the first argument is the array you want to iterate, the second is the function that must be applied to all elements, this function can be an already declared or an anonymous one(clousere)

$array = array(
    'stack' => 'Overflow',
    'linguagem' => 'Português',
    'tags' => array('PHP', 'Iteração', 'Array')
);

array_walk($array, function($v, $k) { 
    var_dump($v, $k);
});

In the case of array_walk_recursive, it will iterate with the elements of array recursively.

Behold:

array_walk_recursive($array, function ($value, $key) {
    var_dump($value, $key);
});

Upshot:

string(8) "Overflow"
string(5) "stack"
string(10) "Português"
string(9) "linguagem"
string(3) "PHP"
int(0)
string(10) "Iteração"
int(1)
string(5) "Array"
int(2)

Example in IDEONE

Example - ideone

  • The irony in the case is that the question is about array, and the guy who answers calls @rray

  • 2

    @Wallacemaxters, lol a @ is another irony too haha.

  • I wonder what he meant?

  • Who @Wallacemaxters?

  • You wanted to assign the @ because PHP omits errors with it?

  • @Wallacemaxters no, some languages use @ to define an array, for example perl and powershell :D

  • Ah, yeah. The ruby also. But it seems that it is to define a global variable

Show 2 more comments

13

I couldn’t help myself without having to give my stick around

Another good way to make this iteration of a array, without the foreach, would be with a while, iterating over an instance of ArrayIterator.

Behold:

 $it = new ArrayIterator($array);

 while ($it->valid()) {

    $indice = $it->key();

    $valor = $it->current();

    $it->next();
 }

Just remembering that to make another iteration, it would be necessary to use the method rewind to return to the pointer at the beginning.

$it->rewind(); // Após o while

12

Still speaking of objects we could do so too:

$array = array(
    'stack' => 'Overflow',
    'linguagem' => 'Português',
    'tags' => array('PHP', 'Iteração', 'Array')
);

$arrayobject = new ArrayObject($array);

$iterator = $arrayobject->getIterator();

while($iterator->valid()) {
    echo $iterator->key() . ' => ' . $iterator->current() . "\n";

    $iterator->next();
}

Important to remember is that we have to use the method next within the while to move to the next element and thus avoid a infinite loop.

I’d fall for your own response concerning the ArrayIterator()

11

You can use the array_walk:

$array = array(
    'stack' => 'Overflow',
    'linguagem' => 'Português',
    'tags' => array('PHP', 'Iteração', 'Array')
);

array_walk($array, function ($value, $key){
    var_dump($key, $value);
});

If the index is irrelevant, array_map can be used

$array = array(
    'stack' => 'Overflow',
    'linguagem' => 'Português',
    'tags' => array('PHP', 'Iteração', 'Array')
);

array_map(function($value)
{
    var_dump($value);
}, $array); 
  • 1

    In the case of array_map would not have the $key, it’s not true ?

  • array_map disregards the index.

  • In fact its purpose is to be used in conjunction with other arrays, but it ends up iterating.

10

Another way to do this is by using the function each.

She picks up the current pointer from array and turns into another array, containing the value of the index and the value of the index array. Then it passes to the next element of the array.

Example;

each($array);

Upshot:

Array
(
    [1] => Portugus
    [value] => Portugus
    [0] => linguagem
    [key] => linguagem
)

See that it returns a key called value and another as a numerical index. This is so that it is possible to use this function with the list.

So we can do this:

while (list($key, $value) = each($array)) {
    var_dump($key, $value);
}

We can also use (oddly) a for for that reason:

for (; list($key, $value) = each($array); ) {
      var_dump($key, $value);
}
  • It would not be more intuitive to use a while since you are omitting the two parameters of the for?

  • It’s true, @Luishenrique. It was really weird coding. But it was just to have an example :)

  • 1

    Note PHP 7.2: the function each now is obsolete will be removed in the future.

9

You can build a Patterns design interaction, as the example below, which is based on PHP Iterator ( http://php.net/manual/en/class.iterator.php ):

 <?php

   //entrada de elementos
    $myCollection = [
        new stdClass(),
        new stdClass(),
        new stdClass(),
        new stdClass(),
    ];
     /**
     * :::: Iterator Interface 
     *
     * @author ivan-ferrer
     */
    interface MyIteratorInterface
    {
        public function current();
        public function rewind();
        public function next();
        public function key();
        public function valid();
    }

    // Estruturais, Comportamentais e Criacionais
    // PHP Iterator

    class PHPIterator implements Iterator, MyIteratorInterface
    {
        private $collection = [];
        private $key        = 0;

        public function __construct(array $collection = [])
        {
            $this->collection = $collection;
        }

        public function rewind()
        {
            $this->key = 0;
        }


        public function current()
        {
            return $this->collection[$this->key];
        }

        public function key()
        {
            return $this->key;
        }

        public function next()
        {
            ++$this->key;
        }


        public function valid()
        {
            return isset($this->collection[$this->key]);
        }
    }

    $phpIterator = new PHPIterator($myCollection);

    echo "-----------------while--------------------\n";
    $phpIterator->rewind();

    while ($phpIterator->valid()) {
        var_dump($phpIterator->current());
        $phpIterator->next();
    }

    echo "-------------------for--------------------\n";


    for ($phpIterator->rewind(); $phpIterator->valid(); $phpIterator->next()) {
        var_dump($phpIterator->current());
    }


    echo "------------------foreach-----------------\n";

    foreach ($phpIterator as $key => $object) {
        var_dump($object);
    }

There are also several other ways to make a iterator: http://php.net/manual/en/spl.iterators.php

  • It’s also a valid way. Even if no one wants to declare a class just to iterate, the important thing is that we’re discussing something out of curiosity :)

  • 1

    How so anyone? I think it is worth both for documentation and to preserve the business rules of a company. In addition it ensures that your code does not lose its purpose of functionality, ensuring consistency and good interpretation of use.

  • I speak to iterate with a array. The meaning of the question really was only out of curiosity. There is no doubt that the best way to iterate with a simple array is using the foreach.

  • The goal of an interface is not to redeclare code, quite the contrary is to avoid "redeclarements", the goal is to build a solid base (a template) to start a project. I think you should study a little more about Interfaces and abstract classes, will help you better understand what it’s for and may one day change your mind...

  • 1

    i guess you don’t understand what I meant. The interface Iterator already contains the 5 methods you have added to your interface. It is not my goal to cause long discussions, but only to give a touch when encoding the answer. I know what the interfaces are for and I understood perfectly your purpose to used (I do it a lot). In fact, by its implementation you only need the Iterator (which is native to PHP), nor does it need MyIterator. That’s what I meant :|

  • I did understand @Wallacemaxters, but it didn’t make much sense to me, when you said that I am "declaring my methods just to iterate", in a high-level development company, this practice is very well accepted, if like me, you want to grow as a developer, I recommend using Interfaces, barely does it, I think it only has to add.

Show 2 more comments

9

It is possible to treat it as an object like this:

$array = array(
    'stack' => 'Overflow',
    'linguagem' => 'Português',
    'tags' => array('PHP', 'Iteração', 'Array')
);


$A = $array;
while(!is_null(key($A))) {
  var_dump(current($A));
  next($A);
}

http://php.net/manual/en/language.oop5.iterations.php

  • 1

    Puts! I figured I had how to do this key($array), but with the for (did not work). It is important to complement the use of key in your case was most correct, since current can return other values considered as boleanos false, causing the iteration "unwanted pause"

  • my suggested edition would be the following: while( ! is_null( $key = key($A))). Then you could access the current index inside the loop in the iteration :)

7

In fact, a loop for does not work well with arrays with non-numeric indexes, but it is possible to circumvent this if "reset" as Keys but are not important, with array_values.

$array = array(
    'stack' => 'Overflow',
    'linguagem' => 'Português',
    'tags' => array('PHP', 'Iteração', 'Array')
);

$numericArray = array_values($array);

$count = count($numericArray);

for ($i = 0; $i < $count; $i++){
    var_dump($numericArray[$i]);
}
  • Thinking that way, you could use the $i with array_values and array_keys. How would you feel about adding that to the answer? $keys = array_keys($meuArray); $keys[$i]; $arrays[$i];

  • @Wallacemaxters in this case my answer would be very similar to an already posted...

  • I understood :). But anyway cries in this Ideone

7

Okay, just fuck with me, here’s my answer:

print_r( $array );

This iterates and already shows on the screen at once, both keys and values.

And best of all, it works on arrays multi-level ;)



Okay, there’s no way to leverage the data for a lot of different things, but if it’s just for show, print_r comes with "complete package".

3

2

Using do ... while:

    do
    {
        $cliente = current($dados_teste); // acessa item atual com "current"
        $tabela.= $cliente['nome'] .'-'. $cliente['idade']; // usa os dados
    }            
    while(next($dados_teste)!==false); // avança o ponteiro com "next"

Sample code:

<?php

    $dados_teste = array(
                            array(
                                    'nome'=>'Pedro',
                                    'idade'=>'45',
                                    'uf'=>'RJ'
                                ),

                            array(
                                    'nome'=>'Maria',
                                    'idade'=>'30',
                                    'uf'=>'RJ'
                                ),    

                            array(
                                    'nome'=>'Miguel',
                                    'idade'=>'28',
                                    'uf'=>'MG'
                                ),    

                            array(
                                    'nome'=>'Paulo',
                                    'idade'=>'52',
                                    'uf'=>'SP'
                                ),                            
                        );


    $tabela = '<table>
        <tr><th>Nome</th><th>Idade</th><th>UF</th></tr>';

    do
    {
        $cliente = current($dados_teste);

        $tabela.= '
        <tr><td>'.$cliente['nome'] .'</td><td>'. $cliente['idade'] .'</td><td>'.  $cliente['uf'] .'</td></tr>';
    }            
    while(next($dados_teste)!==false);    

    $tabela.='
    </table>';   

?><!DOCTYPE HTML>
<html>
<head>
    <title>Exemplo Iterando array com Do...While</title>
    <style>
        table {border-collapse: collapse; }
        th,td { border:1px solid #777; padding:10px; }
    </style>
</head>
<body>
    <?php echo $tabela; ?>

</body>
</html>

Output:

    <!DOCTYPE HTML>
    <html>
    <head>
        <title>Exemplo Iterando array com Do...While</title>
        <style>
            table {border-collapse: collapse; }
            th,td { border:1px solid #777; padding:10px; }
        </style>
    </head>
    <body>
        <table>
            <tr><th>Nome</th><th>Idade</th><th>UF</th></tr>
            <tr><td>Pedro</td><td>45</td><td>RJ</td></tr>
            <tr><td>Maria</td><td>30</td><td>RJ</td></tr>
            <tr><td>Miguel</td><td>28</td><td>MG</td></tr>
            <tr><td>Paulo</td><td>52</td><td>SP</td></tr>
        </table>
    </body>
    </html>

Browser other questions tagged

You are not signed in. Login or sign up in order to post.