Idiom for array index that I'm foreach'ing over?

Discussion in 'Perl Misc' started by Tim Shoppa, Dec 4, 2003.

  1. Tim Shoppa

    Tim Shoppa Guest

    OK, I'm a former (and current!) Fortran programmer. But often I end up
    with Perl data structures where I not only have to step through each element of
    an array, but also must know the index into the array.

    I end up writing code that looks like

    for my $i (0..$#a) {
    my $e = $a[$i];
    # Do stuff with $i and $e here
    }

    That's a bit ugly, I have a numeric loop, an extra variable, that funny
    (0..$#a) construct, etc. And if I have to "last" to bail out of the loop
    I've lost my index and the array element that I bailed out at.

    I'd rather write something like

    for (@a) {
    # Do stuff with $_ and some magical variable telling me the index
    }

    in the same way that I can

    while (<>) {
    # Do stuff with $_ and the line number $. here
    }

    Is there some magical variable like $. for array loops? Any better
    idioms than what I'm currently doing?

    Tim.
     
    Tim Shoppa, Dec 4, 2003
    #1
    1. Advertising

  2. Tim Shoppa

    Lack Mr G M Guest

    In article <>, (Tim Shoppa) writes:
    |>
    |> OK, I'm a former (and current!) Fortran programmer.

    Ah, yes. Real FORTRAN programmer can write FORTRAN in any language :).

    |> But often I end up
    |> with Perl data structures where I not only have to step through each element of
    |> an array, but also must know the index into the array.
    |>
    |> I end up writing code that looks like
    |>
    |> for my $i (0..$#a) {
    |> my $e = $a[$i];
    |> # Do stuff with $i and $e here
    |> }
    |>
    |> That's a bit ugly, I have a numeric loop, an extra variable, that funny
    |> (0..$#a) construct, etc. And if I have to "last" to bail out of the loop
    |> I've lost my index and the array element that I bailed out at.

    So:

    my $i;
    for ($i = 0; $i < @a; $i++) {
    my $e = $a[$i];
    # Do stuff with $i and $e here
    last if ($e > 20_000); # eg: exit statement
    }

    And now, after the loop, $i is still set to the value causing the exit

    |> Is there some magical variable like $. for array loops? Any better
    |> idioms than what I'm currently doing?

    Well, possibly better is:

    my $exiter; # So it is undef
    for (my $i = 0; $i < @a; $i++) {
    my $e = $a[$i];
    # Do stuff with $i and $e here
    if ($e > 20_000) { # eg: exit statement
    $exiter = $i;
    last;
    }
    }

    And now, after the loop, $exiter is set to the value causing the exit
    unless you reached the end of the array, in which case it is still
    undefined.


    --
    --------- Gordon Lack --------------- ------------
    This message *may* reflect my personal opinion. It is *not* intended
    to reflect those of my employer, or anyone else.
     
    Lack Mr G M, Dec 4, 2003
    #2
    1. Advertising

  3. Tim Shoppa

    Anno Siegel Guest

    Tim Shoppa <> wrote in comp.lang.perl.misc:
    > OK, I'm a former (and current!) Fortran programmer. But often I end up
    > with Perl data structures where I not only have to step through each element of
    > an array, but also must know the index into the array.
    >
    > I end up writing code that looks like
    >
    > for my $i (0..$#a) {
    > my $e = $a[$i];
    > # Do stuff with $i and $e here
    > }
    >
    > That's a bit ugly, I have a numeric loop, an extra variable, that funny
    > (0..$#a) construct, etc. And if I have to "last" to bail out of the loop
    > I've lost my index and the array element that I bailed out at.
    >
    > I'd rather write something like
    >
    > for (@a) {
    > # Do stuff with $_ and some magical variable telling me the index
    > }
    >
    > in the same way that I can
    >
    > while (<>) {
    > # Do stuff with $_ and the line number $. here
    > }
    >
    > Is there some magical variable like $. for array loops? Any better
    > idioms than what I'm currently doing?


    Not really. The variable you want has been proposed before, right down
    to the name (re-use the deprecated $#), but it isn't implemented.

    A single variable would be somewhat incomplete. With nested for-loops
    you'd also want a way to access the indices of enclosing loops.

    If you want to keep the last index accessed, a while-loop is easier
    to handle than a for-loop, because it doesn't take privacy of the
    loop variable so serious:


    my $i = 0;
    while ( $i < @array ) {
    # do something with $array[ $i];
    last if bored();
    $i ++; # hi Abigail
    }
    # use $i, it has the last value from the loop

    But that's hardly an idiom, it's just a straight-forward way to do
    something like that.

    It may suffice to know what is left over from the array (the elements that
    have *not* been processed). If so, this is a bit more perlish:

    while ( @array ) {
    my $element = shift @array;
    # do something with $element
    last if bored();
    }
    # now @array is what the loop left over

    If you happen to know the original number of elements in @array,
    "$original_length - @array" is the last index used.

    I say this is "more perlish" because it uses the array as a unit. In
    Fortran, an array is just a declaration, the only things you can actually
    do something with are array elements, and the only way to access them is
    through an index.

    Perl can manipulate arrays as a whole, and doing that makes better
    use of its high-level features. Once you get accustomed to this style,
    you'll find that you rarely want to loop over an index. You loop over
    array elements directly, and in fact map and grep do much of the looping.

    If you actually need random access to elements, more often than not
    the right data structure is a hash and not an array (even if the indices
    happen to be numbers). With hashes, indexed access, and hence loops
    over hash keys, are more frequent than with arrays, though "each" and
    "values" offer alternatives.

    Anno
     
    Anno Siegel, Dec 4, 2003
    #3
  4. Tim Shoppa

    Tim Shoppa Guest

    In article <bqnsfo$ogu$-Berlin.DE>, Anno Siegel says...
    >Perl can manipulate arrays as a whole, and doing that makes better
    >use of its high-level features. Once you get accustomed to this style,
    >you'll find that you rarely want to loop over an index. You loop over
    >array elements directly, and in fact map and grep do much of the looping.
    >
    >If you actually need random access to elements, more often than not
    >the right data structure is a hash and not an array (even if the indices
    >happen to be numbers). With hashes, indexed access, and hence loops
    >over hash keys, are more frequent than with arrays, though "each" and
    >"values" offer alternatives.


    I agree, hashes are great, hashes are wonderful, I love hashes, but
    sometimes the data really is an ordered list.

    I should add that the reason that I want to know the index of the
    current element is to access the same element number in another
    array. (Things like a list of x coordinates in a time series and
    y coordinates in a time series and the time value of each x-y
    coordinates). Given this one-to-one mapping between multiple arrays, it's
    probably best to make one object (possibly hash-based object-oriented
    stuff) which contains x,y, and time for each point. But it seems
    silly to me to go through the whole object paradigm for a simple
    ten-line program, and at the same time it seems a little awkward
    that the hypothetical $# doesn't exist. There are lots of ways to
    make workable programs, it's just that none of them have the
    simplicity and elegance that I expect out of good modern Perl
    that I'm writing :)

    If the program was bigger, I'd go the full object-oriented route
    with modules etc., but it seems silly to do this for such a tiny
    quick little thing.

    Tim.
     
    Tim Shoppa, Dec 4, 2003
    #4
  5. Tim Shoppa

    Ben Morrow Guest

    -berlin.de (Anno Siegel) wrote:
    > my $i = 0;
    > while ( $i < @array ) {
    > # do something with $array[ $i];
    > last if bored();
    > $i ++; # hi Abigail


    I haven't been here long enough to get the 'hi Abigail', but surely
    that should be in a continue block so you can 'next'?

    Also, I would be more inclined to code this as

    my $i = 0;
    for (@array) {
    # do something with $i and $_;
    } continue { $i++ }

    or, as you say, completely restructure the code so I didn't need to
    know what $i was at all :).

    Ben

    --
    Like all men in Babylon I have been a proconsul; like all, a slave ... During
    one lunar year, I have been declared invisible; I shrieked and was not heard,
    I stole my bread and was not decapitated.
    ~ ~ Jorge Luis Borges, 'The Babylon Lottery'
     
    Ben Morrow, Dec 4, 2003
    #5
  6. Tim Shoppa

    Uri Guttman Guest

    >>>>> "TS" == Tim Shoppa <> writes:

    TS> I should add that the reason that I want to know the index of the
    TS> current element is to access the same element number in another
    TS> array. (Things like a list of x coordinates in a time series and
    TS> y coordinates in a time series and the time value of each x-y
    TS> coordinates). Given this one-to-one mapping between multiple
    TS> arrays, it's probably best to make one object (possibly hash-based
    TS> object-oriented stuff) which contains x,y, and time for each
    TS> point. But it seems silly to me to go through the whole object
    TS> paradigm for a simple ten-line program, and at the same time it
    TS> seems a little awkward that the hypothetical $# doesn't exist.
    TS> There are lots of ways to make workable programs, it's just that
    TS> none of them have the simplicity and elegance that I expect out of
    TS> good modern Perl that I'm writing :)

    who says you need objects for that? you need proper perl data
    structures. you really have to stop thinking in fortran!! :)

    perl data structures use references which are not the same as
    objects. to do a 1-1 mapping of two arrays is simple without
    indexes. depending on where the data cam from you can just create a
    array of arrays ( [ x, y ] coordinates ) or even add the time value as
    the third array element. or you could do a simple hash like:

    { x => 1.2,
    y => 3.4,
    time => 12335,
    }

    and have an array or hash of those (not sure what the hash key would
    be).

    TS> If the program was bigger, I'd go the full object-oriented route
    TS> with modules etc., but it seems silly to do this for such a tiny
    TS> quick little thing.

    perl works fine with or without objects. get your mind out of that
    fortran gutter where all you have are individual arrays that can only be
    linked by their indexes. that is such a poor design and paradigm.

    read more about perl data structures in perllol and perldsc.

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
     
    Uri Guttman, Dec 4, 2003
    #6
  7. Tim Shoppa

    Tim Shoppa Guest

    In article <>, Uri Guttman says...
    >perl data structures use references which are not the same as
    >objects. to do a 1-1 mapping of two arrays is simple without
    >indexes. depending on where the data cam from you can just create a
    >array of arrays ( [ x, y ] coordinates ) or even add the time value as
    >the third array element. or you could do a simple hash like:
    >
    > { x => 1.2,
    > y => 3.4,
    > time => 12335,
    > }
    >
    >and have an array or hash of those (not sure what the hash key would
    >be).


    All those are workable but IMHO a bit ugly compared to creating a
    "point" object that has x,y, and time methods. Your last suggestion
    comes close but I don't like all those curly brackets (again, my
    personal taste).

    I did discover Class::MethodMaker which is somewhat elegant for
    this sort of stuff.

    > TS> If the program was bigger, I'd go the full object-oriented route
    > TS> with modules etc., but it seems silly to do this for such a tiny
    > TS> quick little thing.
    >
    >perl works fine with or without objects. get your mind out of that
    >fortran gutter where all you have are individual arrays that can only be
    >linked by their indexes. that is such a poor design and paradigm.


    But it's where my mind goes for any quick-and-dirty program.

    For big programs I'm quite used to the object-oriented approach...
    but then I find that many CPAN modules still insist on, for example,
    arrays ordered the "wrong" way (e.g. GD::Graph), so I'm forced
    to take my elegant objects and break them down to a bunch of arrays
    ("the Fortran gutter").

    I think more use of Class::MethodMaker will satisfy my desire for
    elegance even when quick-and-dirty. And maybe I ought to just not
    use CPAN modules from the Fortran Gutter.

    Tim.
     
    Tim Shoppa, Dec 4, 2003
    #7
  8. Tim Shoppa

    Anno Siegel Guest

    Ben Morrow <> wrote in comp.lang.perl.misc:
    >
    > -berlin.de (Anno Siegel) wrote:
    > > my $i = 0;
    > > while ( $i < @array ) {
    > > # do something with $array[ $i];
    > > last if bored();
    > > $i ++; # hi Abigail

    >
    > I haven't been here long enough to get the 'hi Abigail', but surely


    Oh, that's all about a blank, the one in front of "++". Abigail endorses
    that style, but not everyone follows :)

    > that should be in a continue block so you can 'next'?
    >
    > Also, I would be more inclined to code this as
    >
    > my $i = 0;
    > for (@array) {
    > # do something with $i and $_;
    > } continue { $i++ }


    Sure, that's more robust. I was being sketchy.

    > or, as you say, completely restructure the code so I didn't need to
    > know what $i was at all :).


    As we have learned (news-propagation allowing), the purpose is access
    to two (or more) parallel arrays. Perl isn't particularly good at that,
    though no worse than comparable languages, it just isn't needed all
    that much.

    If you can't avoid parallel lists, I see something like

    for ( map [ $_, shift @yy], @xx ) {
    my ( $x, $y) = @$_;
    print "x: $x, y: $y\n";
    # here we go
    }

    which is slightly obscure and partially destructive. Maybe an indexed
    approach is okay for a ten-liner.

    Anno
     
    Anno Siegel, Dec 4, 2003
    #8
  9. Tim Shoppa

    Anno Siegel Guest

    Tim Shoppa <> wrote in comp.lang.perl.misc:
    > In article <bqnsfo$ogu$-Berlin.DE>, Anno Siegel says...
    > >Perl can manipulate arrays as a whole, and doing that makes better
    > >use of its high-level features. Once you get accustomed to this style,
    > >you'll find that you rarely want to loop over an index. You loop over
    > >array elements directly, and in fact map and grep do much of the looping.
    > >
    > >If you actually need random access to elements, more often than not
    > >the right data structure is a hash and not an array (even if the indices
    > >happen to be numbers). With hashes, indexed access, and hence loops
    > >over hash keys, are more frequent than with arrays, though "each" and
    > >"values" offer alternatives.

    >
    > I agree, hashes are great, hashes are wonderful, I love hashes, but
    > sometimes the data really is an ordered list.
    >
    > I should add that the reason that I want to know the index of the
    > current element is to access the same element number in another
    > array. (Things like a list of x coordinates in a time series and
    > y coordinates in a time series and the time value of each x-y
    > coordinates). Given this one-to-one mapping between multiple arrays, it's
    > probably best to make one object (possibly hash-based object-oriented
    > stuff) which contains x,y, and time for each point. But it seems
    > silly to me to go through the whole object paradigm for a simple
    > ten-line program, and at the same time it seems a little awkward
    > that the hypothetical $# doesn't exist. There are lots of ways to
    > make workable programs, it's just that none of them have the
    > simplicity and elegance that I expect out of good modern Perl
    > that I'm writing :)


    You don't need objects just because you want an advanced data structure
    in Perl. Usually it is possible to build a list of data points (triplets,
    in your case) right from the input.

    If, for some reason, the data is given in individual arrays, there are
    many ways to pre-process them into a list of triplets. I have given an
    example in another article not far from here in this thread.

    The main loop would look like (untested):

    for ( @data_points ) { # @data_points built elsewhere
    my ( $x, $y, $t) = @{ $_}; # $_ is an array(ref) of three elements
    # do things with $x, $y, $t
    }

    Hey, it doesn't even use a hash!

    > If the program was bigger, I'd go the full object-oriented route
    > with modules etc., but it seems silly to do this for such a tiny
    > quick little thing.


    Well, that's one of the beauties of Perl that you can often use just
    enough of it to fit your needs. In this case, an array-ref neatly
    encapsulates your data. This is just an alternative to Uri's hashes-used-
    as-records.

    Anno
     
    Anno Siegel, Dec 4, 2003
    #9
  10. Tim Shoppa

    Uri Guttman Guest

    >>>>> "TS" == Tim Shoppa <> writes:

    >> { x => 1.2,
    >> y => 3.4,
    >> time => 12335,
    >> }
    >>
    >> and have an array or hash of those (not sure what the hash key would
    >> be).


    TS> All those are workable but IMHO a bit ugly compared to creating a
    TS> "point" object that has x,y, and time methods. Your last suggestion
    TS> comes close but I don't like all those curly brackets (again, my
    TS> personal taste).

    but you don't speak perl so you taste is not relevent. even with objects
    you need to understand perl refs.

    TS> I did discover Class::MethodMaker which is somewhat elegant for
    TS> this sort of stuff.

    overkill. you just said you didn't want to go OO for this. make up your
    mind. and you still need to learn refs.

    TS> If the program was bigger, I'd go the full object-oriented route
    TS> with modules etc., but it seems silly to do this for such a tiny
    TS> quick little thing.

    that makes no sense at all.

    >> perl works fine with or without objects. get your mind out of that
    >> fortran gutter where all you have are individual arrays that can only be
    >> linked by their indexes. that is such a poor design and paradigm.


    TS> But it's where my mind goes for any quick-and-dirty program.

    if you want to get better at perl, then you should stop thinking in
    fortran.

    TS> For big programs I'm quite used to the object-oriented approach...
    TS> but then I find that many CPAN modules still insist on, for example,
    TS> arrays ordered the "wrong" way (e.g. GD::Graph), so I'm forced
    TS> to take my elegant objects and break them down to a bunch of arrays
    TS> ("the Fortran gutter").

    huh?

    TS> I think more use of Class::MethodMaker will satisfy my desire for
    TS> elegance even when quick-and-dirty. And maybe I ought to just not
    TS> use CPAN modules from the Fortran Gutter.

    huh?

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
     
    Uri Guttman, Dec 4, 2003
    #10
  11. Tim Shoppa

    Tore Aursand Guest

    On Thu, 04 Dec 2003 07:42:42 -0800, Tim Shoppa wrote:
    > Is there some magical variable like $. for array loops?


    No. You say that you've been programming Fortran, and you're saying - at
    the same time - that you're too lazy to write the following code?

    my $i = 0;
    foreach ( @array ) {
    $_ . ' at position ' . $i . "\n";
    $i++;
    }

    Crazy. :)


    --
    Tore Aursand <>
    "Out of missiles. Out of bullets. Down to harsh language." -- Unknown
     
    Tore Aursand, Dec 5, 2003
    #11
  12. Tim Shoppa

    Brad Baxter Guest

    On Thu, 4 Dec 2003, Anno Siegel wrote:
    > If you can't avoid parallel lists, I see something like
    >
    > for ( map [ $_, shift @yy], @xx ) {
    > my ( $x, $y) = @$_;
    > print "x: $x, y: $y\n";
    > # here we go
    > }
    >
    > which is slightly obscure and partially destructive. Maybe an indexed
    > approach is okay for a ten-liner.


    Here's one non-destructive version:

    my %h;
    @h{@xx}=@yy;
    for ( map [ $_, $h{$_}], @xx ) {
    my ( $x, $y) = @$_;
    print "x: $x, y: $y\n";
    }

    Here's another. :)

    {{
    my $i=0;
    sub rewind{$i=0}
    sub eAch(\@\@){$i>$#{$_[0]}&&$i>$#{$_[1]}?():($_[0][$i],$_[1][$i ++])}
    }}

    while( my( $x, $y ) = eAch( @xx, @yy ) ) {
    print "x: $x, y: $y\n";
    }


    Regards,

    Brad
     
    Brad Baxter, Dec 5, 2003
    #12
  13. On Thu, 4 Dec 2003 19:27:00 +0000 (UTC), Ben Morrow
    <> wrote:

    >> $i ++; # hi Abigail

    ^

    >I haven't been here long enough to get the 'hi Abigail', but surely
    >that should be in a continue block so you can 'next'?


    I *think* it is because of that space. And I can't believe it: it...
    it really works!


    Michele
    --
    # This prints: Just another Perl hacker,
    seek DATA,15,0 and print q... <DATA>;
    __END__
     
    Michele Dondi, Dec 5, 2003
    #13
  14. Also sprach Michele Dondi:

    > On Thu, 4 Dec 2003 19:27:00 +0000 (UTC), Ben Morrow
    ><> wrote:
    >
    >>> $i ++; # hi Abigail

    > ^
    >
    >>I haven't been here long enough to get the 'hi Abigail', but surely
    >>that should be in a continue block so you can 'next'?

    >
    > I *think* it is because of that space. And I can't believe it: it...
    > it really works!


    Well, you can do funny things in Perl, particularly with whitespaces:

    ethan@ethan:~$ perl
    $
    # comment
    bla


    = 5
    ;

    print $bla;
    __END__
    5

    As I recall, Abigail occasionally uses such tricks in an imaginative way
    in his signatures.

    Tassilo
    --
    $_=q#",}])!JAPH!qq(tsuJ[{@"tnirp}3..0}_$;//::niam/s~=)]3[))_$-3(rellac(=_$({
    pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus})!JAPH!qq(rehtona{tsuJbus#;
    $_=reverse,s+(?<=sub).+q#q!'"qq.\t$&."'!#+sexisexiixesixeseg;y~\n~~dddd;eval
     
    Tassilo v. Parseval, Dec 5, 2003
    #14
  15. Tim Shoppa

    Anno Siegel Guest

    Brad Baxter <> wrote in comp.lang.perl.misc:
    > On Thu, 4 Dec 2003, Anno Siegel wrote:
    > > If you can't avoid parallel lists, I see something like
    > >
    > > for ( map [ $_, shift @yy], @xx ) {
    > > my ( $x, $y) = @$_;
    > > print "x: $x, y: $y\n";
    > > # here we go
    > > }
    > >
    > > which is slightly obscure and partially destructive. Maybe an indexed
    > > approach is okay for a ten-liner.

    >
    > Here's one non-destructive version:
    >
    > my %h;
    > @h{@xx}=@yy;
    > for ( map [ $_, $h{$_}], @xx ) {
    > my ( $x, $y) = @$_;
    > print "x: $x, y: $y\n";
    > }


    No. That will generally fail when the elements in @xx aren't unique.

    > Here's another. :)
    >
    > {{
    > my $i=0;
    > sub rewind{$i=0}
    > sub eAch(\@\@){$i>$#{$_[0]}&&$i>$#{$_[1]}?():($_[0][$i],$_[1][$i ++])}
    > }}


    Oh, the double-brace convention. I'm feeling flattered :)

    > while( my( $x, $y ) = eAch( @xx, @yy ) ) {
    > print "x: $x, y: $y\n";
    > }


    Another variation of the each-for-lists theme, with a nice use of
    prototypes. If we had a prototype for "arbitrarily many of \@", this
    could be generalized to a step-by-step transposition routine for any
    number of parallel arrays.

    Anno
     
    Anno Siegel, Dec 5, 2003
    #15
  16. Tim Shoppa

    Tim Shoppa Guest

    Tore Aursand <> wrote in message news:<>...
    > On Thu, 04 Dec 2003 07:42:42 -0800, Tim Shoppa wrote:
    > > Is there some magical variable like $. for array loops?

    >
    > No. You say that you've been programming Fortran, and you're saying - at
    > the same time - that you're too lazy to write the following code?
    >
    > my $i = 0;
    > foreach ( @array ) {
    > $_ . ' at position ' . $i . "\n";
    > $i++;
    > }
    >
    > Crazy. :)


    Creating a brand new variable with scope outside the loop body and no
    use outside the body, which I then have to increment each time
    around the loop (and remember not to "next" before the code that increments
    it), when obviously the computer internally knows the index of the
    element it's working on, isn't crazy?

    And while everyone is telling me that I'm some thick-headed Fortran
    programmer who doesn't know how to use Perl data structures, I
    generally have to generate arrays in these forms because
    other Perl modules from CPAN insist on non-structured arrays of
    X-Y data. (Specifically, GD::Graph and Perl/Tk, but they take their
    arrays in different orders... GD::Graph wants a list of x's and a list of
    y's, while Perl/Tk generally wants x0-y0-x1-y1-x2-y2-etc.). I did
    learn some less-than-elegant idioms for converting to/from these forms, though.

    Tim.
     
    Tim Shoppa, Dec 5, 2003
    #16
  17. Tim Shoppa

    Brad Baxter Guest

    On Fri, 5 Dec 2003, Tim Shoppa wrote:
    > Creating a brand new variable with scope outside the loop body and no
    > use outside the body, which I then have to increment each time
    > around the loop (and remember not to "next" before the code that increments
    > it), when obviously the computer internally knows the index of the
    > element it's working on, isn't crazy?


    Okay, for what it's worth, here's my attempt at cleverness. No, it's not
    exactly what you asked for ...

    {{
    my $i=0;
    sub rewind{$i=0}
    sub it(\@){$i>$#{$_[0]}?():($i+0,$_[0][$i++])}
    }}

    while( my( $i, $it ) = it( @array ) ) {
    print "i: $i, it: $it\n";
    }


    Regards,

    Brad
     
    Brad Baxter, Dec 5, 2003
    #17
  18. On Thu, 4 Dec 2003 23:10:18 -0500, Brad Baxter
    <> wrote:

    >Here's another. :)
    >
    >{{

    ^^
    >my $i=0;
    >sub rewind{$i=0}
    >sub eAch(\@\@){$i>$#{$_[0]}&&$i>$#{$_[1]}?():($_[0][$i],$_[1][$i ++])}
    >}}

    ^^

    Why double braces?!? Ah! Nice JAPH btw...


    Michele
    --
    $\=q.,.,$_=q.print' ,\g,,( w,a'c'e'h,,map{$_-=qif/g/;chr
    }107..q[..117,q)[map+hex,split//,join' ,2B,, w$ECDF078D3'
    F9'5F3014$,$,];];$\.=$/,s,q,32,g,s,g,112,g,y,' , q,,eval;
     
    Michele Dondi, Dec 5, 2003
    #18
  19. Tim Shoppa

    Anno Siegel Guest

    Brad Baxter <> wrote in comp.lang.perl.misc:
    > On Fri, 5 Dec 2003, Tim Shoppa wrote:
    > > Creating a brand new variable with scope outside the loop body and no
    > > use outside the body, which I then have to increment each time
    > > around the loop (and remember not to "next" before the code that increments
    > > it), when obviously the computer internally knows the index of the
    > > element it's working on, isn't crazy?

    >
    > Okay, for what it's worth, here's my attempt at cleverness. No, it's not
    > exactly what you asked for ...
    >
    > {{
    > my $i=0;
    > sub rewind{$i=0}
    > sub it(\@){$i>$#{$_[0]}?():($i+0,$_[0][$i++])}
    > }}
    >
    > while( my( $i, $it ) = it( @array ) ) {
    > print "i: $i, it: $it\n";
    > }


    Drawing in the OPs intentions, this would be required to work for more
    than one array. We can't make the number of arrays entirely arbitrary
    due to limitations in prototypes (or can we?), but this works for up
    to five arrays:

    BEGIN {{
    my $i = -1;
    sub rewind { $i = -1 }

    sub them (;\@\@\@\@\@) {
    $i++; # increment early, so we can return a valid index
    return if $i >= @{ $_[ 0]};
    ( $i, map $_->[ $i], @_);
    }
    }}

    while ( my ( $i, $x, $y, $t) = them( @xx, @yy, @tt) ) {
    print "i: $i, x: $x, y: $y, t: $t\n";
    }

    Of course this is utterly fragile when applied to more than one set
    of arrays, but for the given purpose it would do.

    Anno
     
    Anno Siegel, Dec 5, 2003
    #19
  20. Tim Shoppa

    Ben Morrow Guest

    -berlin.de (Anno Siegel) wrote:
    > BEGIN {{
    > my $i = -1;
    > sub rewind { $i = -1 }
    >
    > sub them (;\@\@\@\@\@) {
    > $i++; # increment early, so we can return a valid index
    > return if $i >= @{ $_[ 0]};
    > ( $i, map $_->[ $i], @_);
    > }
    > }}
    >
    > while ( my ( $i, $x, $y, $t) = them( @xx, @yy, @tt) ) {
    > print "i: $i, x: $x, y: $y, t: $t\n";
    > }
    >
    > Of course this is utterly fragile when applied to more than one set
    > of arrays, but for the given purpose it would do.


    To remove some of the fragility (untested):

    BEGIN {{
    my %i;

    sub rewind (;\@\@\@\@\@) { $i{join "", @_} = -1 }

    sub them (;\@\@\@\@\@) {
    my $set = join "", @_;
    $i{$set} = -1 unless defined $i{$set}; # $i{$set} //= -1;
    $i{$set}++;
    rewind(@_), return if grep { $i{$set} >= @$_ } @_;
    # I'm not sure what we want here... 'if @_ == grep ...' may be better.
    ( $i{$set}, map $_->[$i{$set}], @_);
    }
    }}

    Ben

    --
    For the last month, a large number of PSNs in the Arpa[Inter-]net have been
    reporting symptoms of congestion ... These reports have been accompanied by an
    increasing number of user complaints ... As of June,... the Arpanet contained
    47 nodes and 63 links. [ftp://rtfm.mit.edu/pub/arpaprob.txt] *
     
    Ben Morrow, Dec 5, 2003
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. mike

    find index value of foreach

    mike, Nov 18, 2005, in forum: ASP .Net
    Replies:
    8
    Views:
    747
    Patrick.O.Ige
    Nov 18, 2005
  2. Replies:
    1
    Views:
    21,263
  3. Replies:
    1
    Views:
    262
    Fredrik Lundh
    Aug 26, 2008
  4. Shawn W_
    Replies:
    5
    Views:
    310
    Aldric Giacomoni
    Sep 16, 2009
  5. Tomasz Chmielewski

    sorting index-15, index-9, index-110 "the human way"?

    Tomasz Chmielewski, Mar 4, 2008, in forum: Perl Misc
    Replies:
    4
    Views:
    336
    Tomasz Chmielewski
    Mar 4, 2008
Loading...

Share This Page