Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Idiom for array index that I'm foreach'ing over?

Reply
Thread Tools

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

 
 
Tore Aursand
Guest
Posts: n/a
 
      12-05-2003
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
 
Reply With Quote
 
 
 
 
Brad Baxter
Guest
Posts: n/a
 
      12-05-2003
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
 
Reply With Quote
 
 
 
 
Michele Dondi
Guest
Posts: n/a
 
      12-05-2003
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__
 
Reply With Quote
 
Tassilo v. Parseval
Guest
Posts: n/a
 
      12-05-2003
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$&."'!#+sexisexi ixesixeseg;y~\n~~dddd;eval
 
Reply With Quote
 
Anno Siegel
Guest
Posts: n/a
 
      12-05-2003
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
 
Reply With Quote
 
Tim Shoppa
Guest
Posts: n/a
 
      12-05-2003
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.
 
Reply With Quote
 
Brad Baxter
Guest
Posts: n/a
 
      12-05-2003
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
 
Reply With Quote
 
Michele Dondi
Guest
Posts: n/a
 
      12-05-2003
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;
 
Reply With Quote
 
Anno Siegel
Guest
Posts: n/a
 
      12-05-2003
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
 
Reply With Quote
 
Ben Morrow
Guest
Posts: n/a
 
      12-05-2003

(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] *
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
problem in running a basic code in python 3.3.0 that includes HTML file Satabdi Mukherjee Python 1 04-04-2013 07:48 PM
Making an array wrap, where last index + 1 = first index Shawn W_ Ruby 5 09-16-2009 02:45 PM
Templated array of templates specialized by array index npankey@gmail.com C++ 6 10-12-2008 03:20 PM
sorting index-15, index-9, index-110 "the human way"? Tomasz Chmielewski Perl Misc 4 03-04-2008 05:01 PM
Array Building idiom John-Mason P. Shackelford Ruby 1 08-10-2006 07:46 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57