What is the difference between a generator and an array? What is the difference between a generator and an array? arrays arrays

What is the difference between a generator and an array?


The difference is in terms of efficiency. For example, many languages other than PHP include two range functions, range() and xrange(). This is a really good example of generators and why to use them. Let's build our own:

function range($start, $end) {    $array = array();    for ($i = $start; $i <= $end; $i++) {        $array[] = $i;    }    return $array;}

Now that's really straight forward. However, for large ranges, it takes a HUGE amount of memory. If we tried to run it with $start = 0 and $end = 100000000, we'd likely run out of memory!

But if we used a generator:

function xrange($start, $end) {    for ($i = $start; $i <= $end; $i++) {        yield $i;    }}

Now we use constant memory, yet still have an "array" (like structure) that we can iterate over (and use with other iterators) in the same space.

It doesn't replace an array, but it does provide an efficient way of avoiding to need the memory...

But it also provides savings in terms of the generation of items. Since each result is generated as-needed, you could delay execution (fetching or computing) each element until you needed it. So for example, if you needed to fetch an item from a database and do some complex processing around each row, you could delay that with a generator until you actually need that row:

function fetchFromDb($result) {    while ($row = $result->fetchArray()) {        $record = doSomeComplexProcessing($row);        yield $record;    }}

So if you only needed the first 3 results, you'd only process the first three records.

For more info, I wrote a blog post on this exact subject.


Generators allow for lazy evaluation of complex statements. That way you save memory as you don't have to allocate everything at once.

Besides both being iterable they aren't nearly the same. An array is a data structure, a generator is not.


An array has to contain each value that you're looping over before you start looping; a generator creates each value "on the fly" as it is requested, so a lot less memory;

An array works with the values it contains, and has to be prepopulated with those values; a generator can create values according to special criteria to be used directly... e.g. a fibonnaci sequence, or letters from a non-A-Z alphabet (calculated by the UTF-8 numeric value) effectively allowing alphaRange('א','ת');

EDIT

function fibonacci($count) {    $prev = 0;    $current = 1;    for ($i = 0; $i < $count; ++$i) {        yield $prev;        $next = $prev + $current;        $prev = $current;        $current = $next;    }}foreach (fibonacci(48) as $i => $value) {    echo $i , ' -> ' , $value, PHP_EOL;}

EDIT

Just for fun, here's a generator that will return the Hebrew alphabet as UTF-8 characters

function hebrewAlphabet() {    $utf8firstCharacter = 1488;    $utf8lastCharacter = 1514;    for ($character = $utf8firstCharacter; $character <= $utf8lastCharacter; ++$character) {        yield html_entity_decode('&#'.$character.';', ENT_NOQUOTES, 'UTF-8');    };}foreach(hebrewAlphabet() as $character) {    echo $character, ' ';}