Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number

Using an array element as a loop iterator

by gurpreetsingh13 (Scribe)
on Nov 07, 2013 at 17:26 UTC ( #1061604=perlquestion: print w/replies, xml ) Need Help??
gurpreetsingh13 has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks.

I think this is a simple question. But somehow not working for me.

Can we use an array element as a loop iterator for another array?

Here is the code which fails(Ignoring all strict and other things).

perl -e '@a=(1,2,3);@b=(2,4,6,7);foreach $a[1](@b){print $a[1];}'

Error: syntax error at -e line 1, near "$a["

I have checked. This works with a c-style for loop.

for($a[1]=0;$a[1]<3;$a[1]++){print $b[$a[1]];}

Similar thing works in python. What is the mistake in this due to which it is failing. Would be thankful for your help

Replies are listed 'Best First'.
Re: Using an array element as a loop iterator
by Eily (Vicar) on Nov 07, 2013 at 18:15 UTC

    I suppose you didn't write what you thought you were writing. First, square brackets are not used to make a list, like in python, but an arrayref, which is only one element. So @a contains only one element which is [1,2,3]. @b on the other is indeed an array.

    Could you write what you were intending to in python? If I translate your code it would be something like:

    for each element in @b $a[1] = element print $a[1] done

    If you want to use the indexes in @a to go through @b you can either use a slice (EDIT: not splice ...) of @b :

    @a = (1,2,3); @b = (2,4,6,7); print for @b[@a]; # print for elements of @b with indexes in @a
    Or loop through @a :
    @a = (1,2,3); @b = (2,4,6,7); for $i (@a) { print $b[$i]; }

    NB: As for the error, I guess in for VAR (LIST) VAR can only be a variable, not any lvalue.

      Could you write what you were intending to in python? If I translate your code it would be something like:
      a = [1,2,3] b = [10,11,12,13] for a[1] in b: print a[1]

        That prints all four elements of b

        10 11 12 13
        and then a contains : [1, 13, 3]. So it does not correspond to your C-style for loop where you only print the first three elements, and the second value in the declaration of a is just thrown away.

        To achieve the same result in Perl you can do:

        @a = 1..3; @b = qw/2 4 7 9/; for (@b) {$a[1] = $_; say; }

Re: Using an array element as a loop iterator
by Laurent_R (Abbot) on Nov 07, 2013 at 18:14 UTC

    Maybe you should not ignore strict and the other things. You might have got some indication on your mistakes (although I can't check that now, having no environment right now).

    [1,2,3] is not an array but a reference to an array. So you may want

    my $a = [1, 2, 3];
    my @a = (1, 2, 3);
    This also does not work:
    foreach $a[1](@b)
    Maybe you want something this:
    foreach @$a[1][@b]
    but I am really not sure, because the inner array has not been initialized. Finally,
    is also probably wrong, since @a is a reference to an array. Please explain what you are really trying to do, I can't really figure out.

      Sorry, that was a mistake in copy-paste or something. I have updated the same. I don't want a reference, I am mentioning an array there.
Re: Using an array element as a loop iterator
by jethro (Monsignor) on Nov 07, 2013 at 18:12 UTC

    foreach loops alias each element of the array into the loop variable. AFAIK this alias simply doesn't work with array elements. Since there is no alias happening in a c-style loop there is no problem

Re: Using an array element as a loop iterator
by choroba (Chancellor) on Nov 07, 2013 at 21:07 UTC

    You have to use a scalar variable, possibly preceded by my. The documentation even warns against using tied or special variables.

    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re: Using an array element as a loop iterator
by LanX (Chancellor) on Nov 08, 2013 at 00:11 UTC
    Not sure what you want, you seem to mean the "loop variable" and not an "iterator"¹.

    Anyway like always there is a way to do it in Perl!

    (... but "easy" isn't necessarily the first attribute which comes to mind here... neither is "recommendable"² ;-)

    The following code tries to cover all thinkable use cases:

    my @a="a".."c"; my @b=1..3; print "@a\n"; our $alias; *alias=\$a[2]; { local $a[1]; # otherwise $a[1] is undefined after the loop while ( $a[1] = <@b>) { $alias=$a[1]+1; print "@a\n"; } } print "@a\n"; __END__ a b c a 1 2 a 2 3 a 3 4 a b 4

    Cheers Rolf

    ( addicted to the Perl Programming Language)

    ¹) from perlglossary

    iterator A special programming gizmo that keeps track of where you a +re in something that you’re trying to iterate over. The "foreach +" loop in Perl contains an iterator; so does a hash, allowing you +to each through it.

    ²) NB the elements of @b are stringified in the loop...

Re: Using an array element as a loop iterator
by 2teez (Priest) on Nov 07, 2013 at 19:46 UTC

    Hi gurpreetsingh13,
    if I understand want you want done, is to use the index of one array for another, printing out the value in the other one.
    First of, I will say use a better variable name instead of a and b like you did.
    Secondly, like other monks rightly pointed out, though you have an array variable @a but it contains an arrayref check perlref
    That not withstanding you can get what you want done simply by dereferencing the arrayref and loop through using the index to print the corresponding values in the second array like thus:

    use warnings; use strict; my @array1 = [ 1, 2, 3 ]; my @array2 = ( 2, 4, 6, 7 ); for ( 0 .. $#{ $array1[0] } ) { print $array2[$_], $/; } ## OR print join $/ => @array2[ 0 .. $#{ $array1[0] } ];
    Of course, the answer you get is 2,4 and 6. Atleast that is what you have using the OP as showed by using the C-style for loop, which you supposed worked and indeed it worked since it gave you your desired result,
    BUT did you check your "@a" variable after that to see it values? Please do and see what you have!
    Using Data::Dumper

    If you tell me, I'll forget.
    If you show me, I'll remember.
    if you involve me, I'll understand.
    --- Author unknown to me
Re: Using an array element as a loop iterator
by ww (Bishop) on Nov 07, 2013 at 20:07 UTC

    The question is a bit ambiguous, so for a wild guess on a mental (side?) track distinct from the prior answers I ask "Are you by any chance trying to do this?"

    C:\>perl -e "@a=(1,2,3);@b=(2,4,6,7);for (@a) {print $b[$_];}" 467

    Elements of @a used to print portions of @b; namely, $b[1]...$b[3]

    Others have noted the problem with instantiating @a by using square brackets. Quotes revised for Windows.

      How is "Can we use an array element as a loop iterator for another array?" ambiguous?
        1. For lack of a sample of desired output and the existence of such limited sample data that -- depending on one's reading of the question -- the question can be parsed in at least two, mutually-exclusive ways.
        2. Because of the presence of a fundamental error, noted by others, in declaring the variable @a.
        3. Because here at the Monastery, the possibility always exists that precision in English is NOT a strong suit for an OP.

        The question's ambiguous because it's not well formed (with all due respect to the OP). Consider the following:

        use strict; use warnings; my @a = (2, 4, 6);

        The array elements in the above array are 2, 4 and 6. Can 2 be used as a loop iterator? $a[1] is not an array element. One assumes that $a[1] is the referent of the phrase "array element," but that assumption requires disambiguating the OP's use of that phrase.

        How is "Can we use an array element as a loop iterator for another array?" ambiguous?

        Granted, the question itself seems to be fairly clear, but the code presented to do that is so far from that and so buggy that I just can't make sense of what the OP really wants to do (which is the reason I asked for clarifications). Add to that that the C-style loop (that supposedly works) does something completely different that it just obfuscate further the OP's real intent.

Re: Using an array element as a loop iterator
by GotToBTru (Prior) on Nov 07, 2013 at 19:59 UTC

    Not doing a very good job of reading the OP, people.

    use strict; use warnings; my ($a); my @b=(2,4,6,7); foreach $a (@b) { print $a}

    That works. What if I want to use one element of an array as the iterator? After all, $a[1] is really just a scalar, right?

    use strict; use warnings; my @a=(1,2,3); my @b=(2,4,6,7); foreach $a[1] (@b) { print $a[1] }

    Syntax error though, "near $a[". My guess is perl expects a scalar variable here, and $a[1] isn't a valid scalar variable name, even though it represents a scalar value.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1061604]
Approved by Corion
[1nickt]: thezip use Path::Tiny. @paths = path("/foo")-> children; (Excludes "." and ".." automatically.)
[1nickt]: (Also takes a compiled regexp as an arg to filter the list)
[1nickt]: For multiple dirs use iterator(): $it = path("/foo")-> iterator; while ( my $path = $it->() ) {...}
[1nickt]: (also skips . and .. automatically, and follows subdirs if you set <c\>recurse => 1</c>
[1nickt]: $it = path("/foo")-> iterator(recurse => 1 );

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (12)
As of 2017-03-28 18:45 GMT
Find Nodes?
    Voting Booth?
    Should Pluto Get Its Planethood Back?

    Results (339 votes). Check out past polls.