---
name: "Iterator::Simple"
section: "3pm"
platform: "linux"
package: "libiterator-simple-perl"
version: "0.07-3"
release: "Debian 13 (Trixie)"
platforms: ["linux"]
url: "https://new.carta.tech/Iterator::Simple"
---

# Iterator::Simple(3pm)

Simple iterator and utilities

## NAME

Iterator::Simple - Simple iterator and utilities

## SYNOPSIS

```
  use Iterator::Simple;

  sub foo {
    my $max = shift;
    my $i = 0;
    iterator {
      return if $i > $max;
      $i++;
    }
  }

  my $iterator = foo(20); # yields 0,1,2, ..., 19, 20;
  $iterator = imap { $_ + 2 } $iterator; # yields 2,3,4,5, ... ,20,21,22
  $iterator = igrep { $_ % 2 } $iterator; # yields 3,5,7,9, ... ,17,19,21

  # iterable object
  $iterator = iter([qw(foo bar baz)]); # iterator from array ref
  $iterator = iter(IO::File->new($filename)); # iterator from GLOB

  # filters
  $iterator = ichain($itr1, $itr2); # chain iterators;
  $iterator = izip($itr1, $itr2); # zip iterators;
  $iterator = ienumerate $iterator; # add index;

  # general filter
  $iterator = ifilter $iterator, sub {
    return $_ if /^A/;
    return;
  }

  # how to iterate
  while(defined($_ = $iterator->())) {
    print;
  }

  while(defined($_ = $iterator->next)) {
    print;
  }

  while(<iterator>) {
    print;
  }
```

## DESCRIPTION

Iterator::Simple is yet another general-purpose iterator utilities.

Rather simple, but powerful and fast iterator.

## FUNCTIONS

Iterator::Simple doesn't export any functions by default. please import them like:

```
  use Iterator::Simple qw(iter list imap);
```

For all functions:

```
  use Iterator::Simple qw(:all);
```

- iterator { CODE }

  Iterator constructor. CODE returns a value on each call, and if it is exhausted, returns undef. Therefore, you cannot yields undefined value as a meaning value. If you want, you could use Iterator module which can do that.

  Generally, you can implement iterator as a closure like:

  ```
    use Iterator::Simple qw(iterator);

    sub fibonacci {
      my($s1, $s2, $max) = @_;

      iterator {
        my $rv;
        ($rv, $s1, $s2) = ($s1, $s2, $s1 + $s2);
        return if $rv > $max;
        return $rv;
      }
    }

    my $iterator = fiboacci(1, 1, 1000);
  ```

  You can iterate it in several ways:

  - •

    just call it

    ```
      while(defined($_ = $iterator->())) {
        print "$_\n";
      }
    ```

  - •

    `"next"` method

    ```
      while(defined($_ = $iterator->next)) {
        print "$_\n";
      }
    ```

  - •

    \<\> operator

    ```
      while(<$iterator>) {
        print "$_\n";
      }
    ```

- is\_iterator($object)

  If `$object` is an iterator created by Iterator::Simple, returns true. False otherwise.

- iter($object)

  This function auto detects what `$object` is, and automatically turns it into an iterator. Supported objects are:

  - •

    Iterator made with Iterator::Simple.

  - •

    Object that implements `"__iter__"` method.

  - •

    Object that overloads '\<\>' or has `"next"` method.

  - •

    Object that overloads '&{}'.(as iterator function.)

  - •

    Object that overloads '@{}'.(with `"iarray()"`)

  - •

    ARRAY reference. (`"iarray()"`)

  - •

    CODE reference. (as iterator function.)

  - •

    GLOB reference.

  - •

    nothing (`"iter()"`.) (empty iterator.)

  If it fails to convert, runtime error.

- is\_iterable($object)

  return true if `$object` can be converted with `"iter($object)"`

- list($object)

  This function converts `$object` into single array referece.

  - •

    ARRAY reference.

  - •

    GLOB reference.

  - •

    Iterator made with Iterator::Simple.

  - •

    Object that overloads '@{}' operator.

  - •

    Object that implements '\_\_iter\_\_' method.

  - •

    Object that overloads '\<\>' operator or has `"next"` method.

  - •

    nothing (i.e. **list()** returns \[\]);

  If it fails to convert, runtime error.

  Note that after `"list($iterator)"`, that iterator is not usable any more.

- imap { CODE } $iterable

  This is the iterator version of `"map"`. Returns an iterator which yields the value from source iterator modified by CODE.

- igrep { CODE } $iterable

  This is the iterator version of `"grep"`. Returns an iterator which yields the value from source iterator only when CODE returns true value.

- iflatten $iterable

  When `$iterable` yields another iterator, iterate it first.

  ```
    $subitr = iter([10, 11,12]);
    $source = iter([ 1, 2, $subitr, 4]);

    $flattened = iflatten $source;

    # yields 1, 2, 10, 11, 12, 4.
  ```

- ifilter $iterable, sub{ CODE }

  This is the combination of imap, igrep, iflatten. it supports modify (imap) , skip (igrep), and inflate (iflatten). but it should be faster than combination of them.

  For example:

  ```
    $combination = iflatten
      imap { $_ eq 'baz' ? iter(['whoa', 'who']) : ":$_:" }
      igrep { $_ ne 'bar' }
      iter [ 'foo', 'bar', 'baz', 'fiz' ];
    $itr = iter [ 'foo', 'bar', 'baz', 'fiz' ];
    $filterd = ifilter $itr, sub {
      return if $_ eq 'bar'; #skip
      return iter(['whoa', 'who']) if $_ eq 'baz'; #inflate
      return ":$_:"; # modify
    };
  ```

  Both of them will yields `':foo:', 'whoa', 'who', ':fiz:'`.

- ichain($iterable, $iterable2, ...)

  This function returns an iterator which chains one or more iterators. Iterates each iterables in order as is, until each iterables are exhausted.

  Example:

  ```
    $itr1 = iter(['foo', 'bar', 'baz']);
    $itr2 = iter(['hoge', 'hage']);

    $chained = ichain($itr1, $itr2);

    # yields 'foo', 'bar', 'baz', 'hoge', 'hage'.
  ```

- ienumerate($iterable)

  This function returns an iterator yields like:

  ```
    $ary = iter(['foo', 'bar', 'baz', ... ]);

    $iter = ienumerate $ary;

    # yields [0, 'foo'], [1, 'bar'], [2, 'baz'], ...
  ```

- izip($iterable, $iterable2, ...);

  Accepts one or more iterables, returns an iterator like:

  ```
    $animals = iter(['dogs', 'cats', 'pigs']);
    $says = iter(['bowwow', 'mew', 'oink']);

    $zipped = izip($animals, $says);

    # yields ['dogs','bowwow'], ['cats','mew'], ['pigs', 'oink'].
  ```

  Note that when one of source iterables is exhausted, zipped iterator will be exhausted also.

- islice($iterable, $start, $end, $step)

  Same as islice of itertools in Python. If `$end` is undef or negative value, it iterates source until it is exhausted. `$step` defaults to 1. 0 or negative step value is prohibited.

  ```
    $iter = iter([0,1,2,3,4,5,6,7,8,9,10,11,12]);

    $sliced = islice($iter, 3, 13, 2);
    # yields 3, 5, 7, 9, 11.
  ```

- ihead($count, $iterable)

  ```
    islice($iterable, 0, $count, 1);
  ```

- iskip($count, $iterable)

  ```
    islice($iterable, $count, undef, 1);
  ```

- iarray($arrayref);

  Turns array reference into an iterator. Used in `"iter($arrayref)"`. You do not have to use this function directly, because `"iter($arrayref)"` is sufficient.

## OO INTERFACE

Iterator used in Iterator::Simple is just a code reference blessed in Iterator::Simple::Iterator. This class implements several method and overloads some operators.

- Itrator::Simple::Iterator-\>new($coderef)

  Just bless `$coderef` in Iterator::Simple::Iterator and returns it.

- $iterator-\>next

  Call underlying code.

- $iterator-\>\_\_iter\_\_

  Returns self. You don't need to use this.

- Overloaded operators.

  - •

    Read filehandle operator '\<\>'

    Overloading '\<\>' makes this possible like:

    ```
      print while <$iterator>;
    ```

  - •

    Pipe.. bit\_OR? .. No, pipe!

    ```
      $iterator | $coderef1 | $coderef2;
    ```

    is equivalent to:

    ```
      $iterator->filter($coderef1)->filter($coderef2);
    ```

    is equivalent to:

    ```
      ifilter(ifilter($iterator, $coderef1), $coderef2);
    ```

- $iterator-\>filter($coderef)

  - $iterator-\>**flatten()**

  - $iterator-\>chain($another, ..)

  - $iterator-\>zip($another, ..)

  - $iterator-\>**enumerate()**

  - $iterator-\>slice($start, $end, $step)

  - $iterator-\>head($count)

  - $iterator-\>skip($count)

  For example, `$iterator`-\>**flatten()** is equivalent to `"iflatten $iterator"`.

## TIPS

All iterator transformation function calls `"iter"` function on all source iterables. So you can pass just array reference, GLOB ref, etc.

These examples completely do the right thing:

```
  imap { $_ + 2 } [1, 2, 3, ... ];
  ienumerate(\*STDIN);

  # DBIx::Class::ResultSet has 'next' method.
  ifilter $dbic_resultset, sub {CODE};
```

You can implement `"__iter__"` method on your objects in your application. By doing that, your object will be Iterator::Simple friendly :).

Note that `"__iter__"` method must return an iterator.

## Why Not Iterator.pm

There is another iterator module in CPAN, named Iterator and Iterator::Util made by Eric J. Roode that is great solution. Why yet another iterator module? The answer is \*Speed\*. You use iterator because you have too many data to manipulate in memory, therefore iterator could be called thousands of times, speed is important.

For this simple example:

```
  use Iterator::Util qw(iarray imap igrep);

  for(1 .. 100) {
    my $itr = igrep { $_ % 2 } imap { $_ + 2 } iarray([1 .. 1000]);
    my @result;
    while($itr->isnt_exhausted) {
      push @result, $itr->value;
    }
  }
```

meanwhile:

```
  use Iterator::Simple qw(iarray imap igrep);

  for(1 .. 100) {
    my $itr = igrep { $_ % 2 } imap { $_ + 2 } iarray([1 .. 1000]);
    my @result;
    while(defined($_ = $itr->())) {
      push @result, $_;
    }
  }
```

Iterator::Simple is about ten times faster!

That is natural because Iterator::Simple iterator is just a code reference, while Iterator.pm iterator is full featured class instance. But Iterator::Simple is sufficient for usual demands.

One of most downside of Iterator::Simple is, you cannot yields undef value as a meaning value, because Iterator::Simple thinks it as a exhausted sign. If you need to do that, you have to yield something which represents undef value.

Also, Iterator::Simple cannot determine iterator is exhausted until next iteration, while Iterator.pm has 'is(nt)\_exhausted' method which is useful in some situation.

## AUTHOR

Rintaro Ishizaki \<rintaro@cpan.org\>

## LICENSE

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

## SEE ALSO

- •

  Iterator - Feature rich another iterator class.

- •

  Iterator::Util - Utilities which uses Iterator. Many of filter functions are from this module.
