Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

207
Views
Why does 'iterator_to_array' give different results than foreach?

Suppose I have the following recursive function to turn an array into a Generator:

function traverse(array $items): Generator {
    if (!empty($items)) {
        yield $items[0];

        array_shift($items);
        yield from traverse($items);
    }
}

Running this function and iterating over the Generator through a foreach gives the expected result:

$values = traverse(['a', 'b', 'c', 'd', 'e']);

foreach ($values as $value) {
    echo $value;
}

// 'abcde' is echoed

However, when I use the built-in function iterator_to_array(), I get the following result:

$values = iterator_to_array(traverse(['a', 'b', 'c', 'd', 'e']));

foreach ($values as $value) {
    echo $value;
}

// Only 'e' is echoed

I would expect both pieces of code to behave identically, yet they don't. Why is their behavior different?

I am running this on PHP 8.1.

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

From the manual:

yield from does not reset the keys. It preserves the keys returned by the Traversable object, or array. Thus some values may share a common key with another yield or yield from, which, upon insertion into an array, will overwrite former values with that key.

A common case where this matters is iterator_to_array() returning a keyed array by default, leading to possibly unexpected results. iterator_to_array() has a second parameter use_keys which can be set to false to collect all the values while ignoring the keys returned by the Generator.

Your generator is returning an item with the same key each time (because they are reset after the array_shift call), so iterator_to_array is overwriting each item with the following one. This is why you're only seeing the final element being returned.

If you pass the use_keys argument to the function as false, you'll get the desired behaviour, e.g.

$values = iterator_to_array(traverse(['a', 'b', 'c', 'd', 'e']), false);

See https://3v4l.org/jWbt4

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!