Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Using non-scalar constructs in foreach loops

by periapt (Hermit)
on Mar 17, 2005 at 14:35 UTC ( [id://440380]=perlquestion: print w/replies, xml ) Need Help??

periapt has asked for the wisdom of the Perl Monks concerning the following question:

While working a problem this morning I came across a possible solution that involved assigning sequential values to an array element, doing something and then incrementing the value and doing it again. I wondered if such a think could be done using a foreach loop without a secondary assignment;

Based on my reading, I don't believe that what I want can be done. The foreach construct requires simple scalar variables. That being said, has anyone done it?

For example, a typical solution might be ...
my @tstary = (0,0,0,0,0); print join(":",@tstary),"\n"; foreach my $idx1 (1..3){ $tstary[1] = $idx1; print join(":",@tstary),"\n"; } __OUTPUT__ 0:0:0:0:0 0:1:0:0:0 0:2:0:0:0 0:3:0:0:0
This got me thinking, could I use the array elt itself. The foreach construct doesn't allow a array directly, so how about a referece/dereference ... something like
my @ary03 = (0,0,0,0,0); print join(":",@ary03),"\n"; foreach ${$ary02[3]} (1..3){ $tstary[1] = $idx1; print join(":",@tstary),"\n"; } # this doesn't work with an error of # Can't use string ("0") as a symbol ref while "strict refs" in use # other variations didn't work either # how about $aryeltref = \$ary03[1]; foreach $aryeltref (1..3){ print join(":",(@tstary,$aryeltref)),"\n"; } __OUTPUT__ 0:0:0:0:0:SCALAR(0x2144a28) 0:0:0:0:0:1 0:0:0:0:0:2 0:0:0:0:0:3 # expected but not quite what I had in mind # trying foreach $$aryeltref (1..3) produced a "Not a GLOB reference a +t ... " which makes me wonder if some mojo with the symbol table migh +t make it work?
Just a couple of thoughts on a rainy Thursday morning

By the way, I know I can use the three arg for construct for this. I'm just trying to push the boundary of the foreach construct a little


PJ
use strict; use warnings; use diagnostics;

Replies are listed 'Best First'.
Re: Using non-scalar constructs in foreach loops
by Roy Johnson (Monsignor) on Mar 17, 2005 at 14:50 UTC
    The index variable of a foreach loop is locally aliased to each of the elements of the list, in turn. That is not the same as being assigned to each value; instead, it's more like being a reference that is implicitly dereferenced. The index variable is just another name for whatever is in the list. The actual data you want to work with must be in the list. Like
    foreach my $i (@tstary[1,1,1]) { # or (($tstary[1])x3) ++$i; print join(':', @tstary), "\n"; }

    Caution: Contents may have been coded under pressure.
Re: Using non-scalar constructs in foreach loops
by sh1tn (Priest) on Mar 17, 2005 at 14:53 UTC
    What's wrong in this way?
    my @a = (0,0,0,0); $a[$_-1] = $_, print join(':',@a),"\n" for 1..@a; $a[$_-1] = $_, print join(':',@a),"\n" for 1..@a; $a[@a-$_] = $_, print join(':',@a),"\n" for 1..@a; __END__ STDOUT: 1:0:0:0 1:2:0:0 1:2:3:0 1:2:3:4 1:2:3:4 1:2:3:4 1:2:3:4 1:2:3:4 1:2:3:1 1:2:2:1 1:3:2:1 4:3:2:1


Re: Using non-scalar constructs in foreach loops
by Jasper (Chaplain) on Mar 17, 2005 at 17:47 UTC
    I've written foreaches using array refs, hash refs, objects, you name it. The fact that a foreach must use a scalar value (ie a string or a ref or whatever) does not limit the amount of data that you can effectively pass in via that scalar.

    I see from your code that you've already considered that, but it's not entirely clear in my mind what you're trying to do. It seems to me that what you ought to be trying is to create an unitialised multi-dimensional array, then foreaching through slices through the array and assigning values that way. A slice one way is trivial @{$array[0]}[foo..bar], the other way slightly more complicated map $array[$_]->[0], foo..bar, perhaps.

    Since I've not grasped what you want, I'm probably rambling.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://440380]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (3)
As of 2024-04-20 02:10 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found