NAME

Iterator::Flex::Gather - Gather Iterator Class

VERSION

version 0.28

METHODS

new

use Iterator::Flex::Gather::Constants ':all';

$iterator = Ierator::Flex::Gather->new( $coderef, $iterable, ?\%pars );

Returns an iterator which accumulates elements returned by $iterable based upon the return result of $coderef. Gathered items are returned as an arrayref.

$iterable is converted into an iterator via "to_iterator" in Iterator::Flex::Factory if required.

$coderef is called with the next item from iterable in the $_ variable, and two parameters; the first is an arrayref containing the gathered items, the second is a flag indicating whether the coderef is called while gathering items (GATHER_GATHERING)or after the source has been exhausted (GATHER_SRC_EXHAUSTED).

It should return the binary AND of two result codes.

The first result code indicates whether the the element should be gathered, and must be one of

  • GATHER_ELEMENT_INCLUDE

    The element is gathered.

  • GATHER_ELEMENT_EXCLUDE

    The element is discarded.

  • GATHER_ELEMENT_CACHE

    The element is neither gathered, nor discarded, but is cached, and it is used instead of calling $iterable for the next element This is only of use when a cycle is restarted due to a difference in element values. See "EXAMPLES/Gather into groups based on the value of a key" for an example on how to use this.

    This may only be used in conjunction with "GATHER_CYCLE_RESTART"; an exception is thrown otherwise.

The second indicates whether the gathering cycle should stop and if so, whether it should be restarted. It must be one of

  • GATHER_CYCLE_CONTINUE

    Continue gathering.

  • GATHER_CYCLE_RESTART

    Stop gathering, and return the gathered items. The next time the iterator is invoked, it will begin a new cycle.

  • GATHER_CYCLE_STOP

    Stop gathering, and return the gathered items. The next time the iterator is invoked, it will signal exhaustion.

  • GATHER_CYCLE_ABORT

    Stop gathering, and signal exhaustion. Any gathered items are discarded.

The optional %pars hash may contain standard signal parameters as well as the following model parameters:

  • cycle_on_exhaustion

    When the $iterable signals exhaustion, the gather iterator most likely will have gathered elements which have not yet been returned.

    The "cycle_on_exhaustion" parameter may be used to specify how to handle that case.

    • GATHER_CYCLE_STOP

      If any items have been gathered and not returned, they will be returned and the gather iterator will signal exhaustion when next invoked.

      If there are no items to return, the gather iterator will signal exhaustion.

      This is the default.

    • GATHER_CYCLE_ABORT

      The gather iterator will signal exhaustion, and any gathered items will be lost.

    • GATHER_CYCLE_CHOOSE

      Call $coderef one last time, with $state set to GATHER_SRC_EXHAUSTED. $coderef should return either GATHER_CYCLE_STOP or GATHER_CYCLE_ABORT.

The iterator supports the following capabilities:

next
reset
rewind

INTERNALS

EXAMPLES

Gather only even numbers

sub ( $gathered, $state ) {
    return GATHER_CYCLE_CONTINUE | (
        $_ % 2
        ? GATHER_ELEMENT_EXCLUDE
        : GATHER_ELEMENT_INCLUDE
    );
  }

Batch into groups of 10 elements

Consider using Iterator::Flex::Chunk.

Add the current element to the gathered list

sub ( $gathered, $state ) {
    return GATHER_ELEMENT_INCLUDE
      | ( $gathered->@* == (10 - 1) ? GATHER_CYCLE_RESTART : GATHER_CYCLE_CONTINUE );
}

Save the current element for the next gather

sub ( $gathered, $state ) {
    return ( $gathered->@* == 10 )
      ? GATHER_ELEMENT_CACHE | GATHER_CYCLE_RESTART
      : GATHER_ELEMENT_INCLUDE | GATHER_CYCLE_CONTINUE;
  }

Gather into groups based on the value of a key

Need to cache the current value if it belongs in the next group. Input elements are hashes; select group based upon group key.

Create the iterator with

sub ( $gathered, $state ) {

    # if nothing in the list, charge ahead
    return GATHER_ELEMENT_INCLUDE | GATHER_CYCLE_CONTINUE
      if ! $gathered->@*;

    # If the current element's key is the same as the last
    # gathered one, gather
    return GATHER_ELEMENT_INCLUDE | GATHER_CYCLE_CONTINUE
      if $gathered->[-1]{group} eq $_->{group};

    # have a different key, need to start a new group. cache
    # the current value to use in the next cycle
    return GATHER_ELEMENT_CACHE | GATHER_CYCLE_CONTINUE;
}

Far too complex an example

Batch integer elements into groups of 10, only accept even numbers, and drops the last batch if it has fewer than ten, but only if the last element isn't 100.

sub ( $gathered, $state ) {

    return $gathered->@* && $gathered->[-1] == 100 ? GATHER_CYCLE_STOP : GATHER_CYCLE_ABORT
      if $state == GATHER_SRC_EXHAUSTED;

    return GATHER_ELEMENT_EXCLUDE | GATHER_CYCLE_CONTINUE
      if $_ % 2;

    return GATHER_ELEMENT_INCLUDE
      | ( $gathered->@* == 9 ? GATHER_CYCLE_RESTART : GATHER_CYCLE_CONTINUE );
}

SUPPORT

Bugs

Please report any bugs or feature requests to bug-iterator-flex@rt.cpan.org or through the web interface at: https://rt.cpan.org/Public/Dist/Display.html?Name=Iterator-Flex

Source

Source is available at

https://gitlab.com/djerius/iterator-flex

and may be cloned from

https://gitlab.com/djerius/iterator-flex.git

SEE ALSO

Please see those modules/websites for more information related to this module.

AUTHOR

Diab Jerius <djerius@cpan.org>

COPYRIGHT AND LICENSE

This software is Copyright (c) 2018 by Smithsonian Astrophysical Observatory.

This is free software, licensed under:

The GNU General Public License, Version 3, June 2007