Re: Passing multiple arrays to foreach loop
by Athanasius (Archbishop) on May 11, 2013 at 02:17 UTC
|
It’s legal, because a foreach loop iterates over a list, not an array. In this case, the list consists of the elements in the array @files, followed by the elements in the array @files2, followed by the elements in the array @files3. The lengths of the arrays are irrelevant.
See perlsyn#Foreach-Loops and perldata#List-value-constructors.
Hope that helps,
| [reply] [d/l] [select] |
Re: Passing multiple arrays to foreach loop
by toolic (Bishop) on May 11, 2013 at 01:09 UTC
|
use warnings;
use strict;
my @f1 = qw(x y z);
my @f2 = qw(a b);
for (@f1, @f2) {
print "$_\n";
}
__END__
x
y
z
a
b
| [reply] [d/l] |
Re: Passing multiple arrays to foreach loop
by AnomalousMonk (Archbishop) on May 11, 2013 at 04:08 UTC
|
The only situation in which you will get into trouble is if you include an honest-to-goodness list literal in your for-loop iteration list and then try to do some mutating operation on it.
>perl -wMstrict -le
"my @ra1 = qw(foo bar);
my @ra2 = qw(does not get here);
;;
for my $file (@ra1, 'zonk', @ra2) {
$file .= '-appendage';
print qq{'$file'};
}
"
'foo-appendage'
'bar-appendage'
Modification of a read-only value attempted at -e line 1.
| [reply] [d/l] [select] |
Re: Passing multiple arrays to foreach loop
by GrandFather (Saint) on May 11, 2013 at 09:43 UTC
|
Did you try it? Did it work?
It took me about a minute to write and run:
#!/usr/bin/env perl
use warnings;
use strict;
my @files1 = 1 .. 3;
my @files2 = 4 .. 6;
for my $file (@files1, @files2) {
print "$file\n";
}
which prints:
1
2
3
4
5
6
Actually the first three lines are boiler plate so I didn't actually write those as part of the test so really I only wrote two more lines than your sample code. If you'd have tried it yourself you'd have had a yes/no answer in about the time it took to write your question and probably about 1/5th the time it took for you to see the first answer.
True laziness is hard work
| [reply] [d/l] [select] |
|
| [reply] |
|
deshdaaz asked if this code legal or no. Who knows maybe this code works but considered as dirty hack, or considered deprecated.
| [reply] |
|
|
|
Yes Sir, I did try and it did work. However my actual code goes through more than thousand files and I was not certain if it actually completed all three arrays or not hence the question. Sorry for the trouble.
| [reply] |
|
From all the answers you got, the one from Athanasius was IMHO the best so far.
It's elementary for Perl that @arrays and %hashes are flattened in list context, not only in the case of a foreach (LIST), but whenever the docs talk about "LIST" as parameter.
from perldata#List value constructors
LISTs do automatic interpolation of sublists. That is, when a LIST is evaluated, each element of the list is evaluated in list context, and the resulting list value is interpolated into LIST just as if each individual element were a member of LIST. Thus arrays and hashes lose their identity in a LIST--the list
(@foo,@bar,&SomeSub,%glarch)
contains all the elements of @foo followed by all the elements of @bar, followed by all the elements returned by the subroutine named SomeSub called in list context, followed by the key/value pairs of %glarch.
for instance
DB<105> @a=1..3
=> (1, 2, 3)
DB<106> @b=a..c
=> ("a", "b", "c")
DB<107> @c=(@a,@b)
=> (1, 2, 3, "a", "b", "c")
HTH! =)
Cheers Rolf
( addicted to the Perl Programming Language)
| [reply] [d/l] [select] |
|
It was not "trouble", and actually not a bad question, but learning to write small test programs to check your understanding is a very useful art. The same art applies when the question grows beyond anything one can answer for oneself, but then the art morphs into being able to create a small focused test script that others can use as a test bed for understanding your issue and providing a solution.
True laziness is hard work
| [reply] |
Re: Passing multiple arrays to foreach loop
by Random_Walk (Prior) on May 11, 2013 at 07:48 UTC
|
This will work and you will itterate a list containing each element from each array. If you should want to be able to tell which array is which then you can itterate references instead.
use strict; use warnings;
my @foo = qw(one two three);
my @bar = qw(four five six);
my @baz = qw(seven eight nine);
my $i = 0;
for my $array_ref (\@foo, \@bar, \@baz) { # pass references
print "starting array: ".++$i."\n";
for (@$array_ref) { # de-reference
print " array: $i val: $_\n";
}
}
Cheers, R.
Pereant, qui ante nos nostra dixerunt!
| [reply] [d/l] |