The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Data::Iter - easily iterate over a hash/array

SYNOPSIS

   my @obj = iter( $href );
   
   my @obj = iter( $aref );

EXAMPLE "Function Interface with exported iter()"

 use Data::Iter qw(:all);
   
     # as 'loop' functions
         
   foreach ( iter [qw/Mon Tue Wnd Thr Fr Su So/] )
   {            
     printf "Day: %s [%s]\n", VALUE, COUNTER;
   }

   foreach ( iter { 1 => 'one', 2 => 'two', 3 => 'three', 4 => 'four' } )
   {    
     printf "%10s [%10s] %10d\n", KEY, VALUE, COUNTER;
                 
     print "End.\n" if COUNTER == LAST_COUNTER;
   }

   # An array is handles like a hash (preserves order of elements which hash's don't)

   foreach ( iter [qw(one 1 two 2 three 3)] )
   {            
      if( COUNTER() % 2 == 0 )
      {
          printfln q{%s => %s}, VALUE, GETNEXT->VALUE;
      }
   }

EXAMPLE "OO Interface"

 use Data::Iter;

     # as 'loop' methods
         
   foreach ( Data::Iter->iter [qw/Mon Tue Wnd Thr Fr Su So/] )
   {            
     printf "Day: %s [%s]\n", $_->value, $_->counter;
   }

   foreach my $i ( iter [qw/Mon Tue Wnd Thr Fr Su So/] )
   {            
      printfln q{Day: %s [%s].  Next is %s     returned by $i->getnext()}, $i->VALUE, $i->counter, $i->getnext ? $i->getnext->VALUE : 'undef';
   }

   foreach ( Data::Iter->iter { 1 => 'one', 2 => 'two', 3 => 'three', 4 => 'four' } )
   {    
     printf "%10s [%10s] %10d\n", $_->key, $_->value, $_->counter;
   }

EXAMPLE "Modify during loop"

   my $h = { 1 => 'one', 2 => 'two', 3 => 'three', 4 => 'four' }

   foreach ( Data::Iter->iter( $h )  )
   {    
     printf "%10s [%10s] %10d\n", $_->key, $_->value( $_->value." camel" ), $_->counter;
   }

   # $h->{1} = 'one camel'
   # ...

DESCRIPTION

Data::Iter provides functions for comfortably iterating over perl data structures. Its slower, but easier to code. An array containing object elements for every iteration is generated with the iter() function - due to array'ish nature of for(), foreach() and map() loops it is easy to use.

FUNCTIONS AND METHODS

iter

Accepts a reference to an ARRAY or HASH. Returns a sorted list of 'Data::Iter' objects. So you can use methods (or functions) during looping through this objects.

KEY( $newvalue )

Returns the current key (The key of the HASH entry).

Same as $_->key( $newvalue )

[Note] For ARRAYs it is identical to COUNTER.

[Info] $newvalue is ignored. It is not implemented to set the original key, because i need help from a perl-guru for this advanced stuff.

VALUE( $newvalue )

Returns the current key (HASHs only). $newvalue is optional, but when given sets the original key.

Same as $_->value( $newvalue )

COUNTER()

 $_->counter()

Returns the current counter (starting at 0).

LAST_COUNTER()

Returns the highest counter. Its a synonmy for the length of the list-1.

IS_LAST(), IS_FIRST()

Returns true if is the highest or first counter, respectively.

getvalue( index )

Returns the value at index. It behaves like an array index.

GET( index )

Returns the Data::Iter object at index. It behaves like an array index.

Same as $_->get( index )

CAVE: Future variables are read-only ! It is the common "foreach( @something ) not change during iteration through it" story.

Example:

        get(-1) will return the last iterator object. 
        
        get(-1)->counter will return the position of the last

        get(-1)->value will return the value of the last
        
        get(1+counter) will return the next object (same as getnext())

GETNEXT()

Returns the next Data::Iter object. It is a shortcut for get(1+counter).

Same as $_->getnext;

GETPREV()

Returns the prev Data::Iter object. It is a shortcut for get(counter-1).

PAIR()

Hash's can be imitated by arrays. The advantage is that then you can imitate an ordered hash. PAIR returs and array of

 ( KEY, VALUE )

pair when the iteration is at the right element or undef when it isnt. See here

    foreach my $r ( iter [qw(b red a white)] )
    {
       my ( $key, $value ) = $r->PAIR() 

       if( defined $value )
       {
       }
    }

Note: You have to test for undef of $key or $value, as pair returns every 2nd time a valid result.

$Data::Iter::Sort

This is per default { $a cmp $b } as you know it from sort. One may set a it to an arbitrary sub ref that would normally given to sort. Two function are defined in the Data::Iter namespace per default.

    sub sort_alpha($$) { $_[0] cmp $_[1] }
    sub sort_num($$) { $_[0] <=> $_[1] }

As to use on of these, just set

 $Data::Iter::Sort = 'sort_alpha'

for alphanumeric sorting.

[NOTE] Note that the $Sort var holds only a subroutine name, and not any reference ! As the $Data::Iter::Sort variable is evaluated in its namespace the value "sort_alpha" will be expanded to the namespace "Data::Iter::sort_alpha" which indeed is the right place of the function.

If you have really an own sort routine, than place it somewhere and set its name (with full namespace) to the $Sort variable:

 my $str3;

 sub sort_wild($$) { $_[0]+$_[1] <=> $_[1] }

 $Data::Iter::Sort = "::sort_wild";

        foreach ( iter \%numbers )
        {       
                $str3.=key;
        }

 println $str3;

[Note] "::sort_wild" refers to the 'main::' namespace, where this snippet was placed.

HIGHER FUNCTIONS

$hash_ref = transform_array_to_hash( $array_ref )

 $array_ref =
    [
    tcf1 => 28.44
    tcf1 => 28.13
    tcf3 => 26.92
    tcf3 => 26.09
    gapdh => 17.08
    gapdh => 16.1
    ];

Then a call

  transform_array_to_hash( $array_ref )

will return this hash

 {
   gapdh => ["17.08", "16.1"],
   tcf1  => ["28.44", "28.13"],
   tcf3  => ["26.92", "26.09"],
 }

BUGS

Not get(counter+1), but get(1+counter) will function correctly (under perl 5.6.0).

And get(counter - 1) does not work.

FUTURE

Add some decent $Data::Iter::options

  • counter base value (for example start from 1 instead of 0).

EXPORT

none by default.

'all' => (iter counter COUNTER LAST_COUNTER value VALUE key KEY get GET getnext GETNEXT)

PITFALLS

You should use iter() only on 'quite' static structures. Since the static precalculated iterations are not tied to the original data structure. So its changes will not be updated.

AUTHOR

Murat Uenalan, <muenalan@cpan.org>

SEE ALSO

Class::Iter, Tie::Array::Iterable, Object::Data::Iterate