I was also thinking about iterators, I like the idea and I have written quite a number of them over the last years. Here, however, I would tend to prefer only one iterator that would keep a buffer of the unused A values and return a pair of A and B values when needed.

The following was written directly at the command line and is not an iterator (in the sense that it is not a subroutine returning the next relevant element), but it is iterating only once over the input data and it would be simple to put that code into an iterator closure that would keep track of the A buffer and return the A and the B values on demand:

$ perl -e ' > use strict; > use warnings; > my @in = split /\n/, > "a 123 > a 125 > b 127 > a 129 > a 130 > b 131 > a 132 > b 133"; > > my @a_buff; > for (@in) { > push @a_buff, $_ and next if /a/; > my $aa = shift @a_buff; # avoid to use the $a special variable > my $diff = $2 - $1 if "$aa - $_" =~ /(\d+)[^\d]*(\d+)/; > print "$aa ; $_ => $diff\n"; > } > ' a 123 ; b 127 => 4 a 125 ; b 131 => 6 a 129 ; b 133 => 4
Update: I have now done a full-fledged iterator as a closure:
use strict; use warnings; my $iter = create_iter(); while (my ($aa, $bb) = $iter->()) { last unless defined $bb; my $diff = $2 - $1 if "$aa $bb" =~ /(\d+)[^\d]*(\d+)/; print "$aa ; $bb => $diff\n"; } sub create_iter { my @a_buff; return sub { while (<DATA>){ chomp; push @a_buff, $_ and next if /a/; return shift @a_buff, $_; } } } __DATA__ a 123 a 125 b 127 a 129 a 130 b 131 a 132 b 133
And this prints the same result:
$ perl iter_pairs.pl a 123 ; b 127 => 4 a 125 ; b 131 => 6 a 129 ; b 133 => 4
Update 2: the same using a state variable (we are stuck with old versions of Perl at work, so I sometimes don't think about such relatively new features which, in this case, make the code a bit simpler than a closure):
use strict; use warnings; use feature "state"; while (my ($aa, $bb) = iter()) { last unless defined $bb; my $diff = $2 - $1 if "$aa $bb" =~ /(\d+)[^\d]*(\d+)/; print "$aa ; $bb => $diff\n"; } sub iter { state @a_buff; while (<DATA>){ chomp; push @a_buff, $_ and next if /a/; return shift @a_buff, $_; } } __DATA__ a 123 ...

Je suis Charlie.

In reply to Re^2: processing a list of events by Laurent_R
in thread processing a list of events by BluePerlDev

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.